1

我曾考虑将 Unity C# 代码(我只能与 UnityEngine 一起使用的代码)与“普通”C# 代码(int x = 3; bool isKnockMeDead = true; void KnockMeDead();等)分开。

为什么?这样我就可以(例如)从 Unity 切换到 Wpf,而无需重写整个逻辑。所以我的 EngineObject 是 Window 而不是 MonoBehviour ......

对于这个问题,我已经有了一些解决方案:

但我对其中任何一个都不是100%满意,因为...

第一个解决方案 - InheritanceSolution.cs

这是执行此操作的最快方法,但您没有 100% 的视觉分离,并且还给出了在 Child 类中使用 Unity Code 的危险。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace Assets
{
    //Unity C#
    public class InheritanceSolutionParent : MonoBehaviour
    {
        public MusicPlayer EngineMusicPlayer { get; private set; }

        public void SetObjectName(string name)
        {
            gameObject.name = name;
        }

        public void MoveObjectUp(decimal y)
        {
            gameObject.transform.position += new Vector3(0, (float)y);
        }
    }

    public class MusicPlayer : MonoBehaviour, IMusicPlayer
    {
    }

    //C#
    public class InheritanceSolutionChild : InheritanceSolutionParent // => Unity
    {
        private IMusicPlayer _universalMusicPlayer;
        private List<Sound> _sounds;

        public void Start() /* => Unity */ => UniversalStart();
        public void Update() /* => Unity */ => UniversalUpdate();

        private void UniversalStart()
        {
            Initionalization();

            _sounds.Add(new Sound("Toilettenspülung", "Assets/Sounds/Toilettenspülung.mp3"));

            _universalMusicPlayer.Play(_sounds[0]);
        }

        private void Initionalization()
        {
            SetObjectName("PartialSolution");
            _universalMusicPlayer = EngineMusicPlayer; // => Unity
            _sounds = new List<Sound>();
        }

        private void UniversalUpdate()
        {
            MoveObjectUp(5);
            MoveObjectUp(2);
        }
    }

    public class Sound
    {
        public Sound(string soundName, string soundFileDataPath)
        {
            SoundName = soundName;
            SoundFileDataPath = soundFileDataPath;
        }

        public string SoundName { get; private set; }
        public string SoundFileDataPath { get; private set; }
    }

    public interface IMusicPlayer
    {
        void Play(Sound sound);
    }
}

第二个解决方案 - PartialSolution.cs

如果几个人想要在一个类上工作而不被打扰和/或如果自动生成的代码应该与用户分开,则实际使用该关键字。

我只是用它来分隔代码,这可以,但它不应该用来说每个类都有200行,因为它在编译时只是保留一个类。

还有问题:/

视觉分离将是完美的,但实现中没有任何变化,我仍然可以在两个(一个)类中使用 Unity 代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace Assets
{
    //Unity C#
    public partial class PartialSolution : MonoBehaviour 
    {
        [SerializeField] private MusicPlayer _engineMusicPlayer;

        private void Start() => UniversalStart();
        private void Update() => UniversalUpdate();

        private void SetObjectName(string name)
        {
            gameObject.name = name;
        }

        private void SetUniversalMusicPlayer()
        {
            _universalMusicPlayer = _engineMusicPlayer;
        }

        private void MoveObjectUp(decimal y)
        {
            gameObject.transform.position += new Vector3(0, (float)y);
        }
    }

    public class MusicPlayer : MonoBehaviour, IMusicPlayer
    {
    }

    //C#
    public partial class PartialSolution
    {
        private IMusicPlayer _universalMusicPlayer;
        private List<Sound> _sounds;

        private void UniversalStart()
        {
            Initionalization();

            _sounds.Add(new Sound("Toilettenspülung", "Assets/Sounds/Toilettenspülung.mp3"));

            _universalMusicPlayer.Play(_sounds[0]);
        }

        private void Initionalization()
        {
            SetObjectName("PartialSolution");
            SetUniversalMusicPlayer();
            _sounds = new List<Sound>();
        }

        private void UniversalUpdate()
        {
            MoveObjectUp(5);
            MoveObjectUp(2);
        }
    }

    public class Sound
    {
        public Sound(string soundName, string soundFileDataPath)
        {
            SoundName = soundName;
            SoundFileDataPath = soundFileDataPath;
        }

        public string SoundName { get; private set; }
        public string SoundFileDataPath { get; private set; }
    }

    public interface IMusicPlayer
    {
        void Play(Sound sound);
    }
}

第三个解决方案 - InterfaceSolution.cs

(Ey Max 请将 GameController 类(大项目)分开...

呃……得跑了

解决方案其实是完美的,但是付出的努力是相当大的!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace Assets
{
    //Unity C#
    public class InterfaceSolutionUnity : MonoBehaviour, IInterfaceSolutionUniversalEngine
    {
        IInterfaceSolutionUniversal _universalInstance;

        [SerializeField] private MusicPlayer _musicPlayer;

        public void Start()
        {
            _universalInstance = new InterfaceSolutionUniversal(this, _musicPlayer);
            _universalInstance.UniversalStart();
        }

        public void Update() => _universalInstance.UniversalUpdate();

        public void SetObjectName(string name)
        {
            gameObject.name = name;
        }

        public void MoveObjectUp(decimal y)
        {
            gameObject.transform.position += new Vector3(0, (float)y);
        }
    }

    public class MusicPlayer : MonoBehaviour, IMusicPlayer
    {
    }

    //C#
    public interface IInterfaceSolutionUniversal
    {
        void UniversalStart();
        void UniversalUpdate();
    }

    public class InterfaceSolutionUniversal : IInterfaceSolutionUniversal
    {
        private IInterfaceSolutionUniversalEngine _universalEngineInstance;

        private IMusicPlayer _musicPlayer;
        private List<Sound> _sounds;

        public InterfaceSolutionUniversal(IInterfaceSolutionUniversalEngine universalEngineInstance, IMusicPlayer musicPlayer)
        {
            _universalEngineInstance = universalEngineInstance;
            _musicPlayer = musicPlayer;
            _sounds = new List<Sound>();
        }

        public void UniversalStart()
        {
            _universalEngineInstance.SetObjectName("PartialSolution");

            _sounds.Add(new Sound("Toilettenspülung", "Assets/Sounds/Toilettenspülung.mp3"));

            _musicPlayer.Play(_sounds[0]);
        }

        public void UniversalUpdate()
        {
            _universalEngineInstance.MoveObjectUp(5);
            _universalEngineInstance.MoveObjectUp(2);
        }
    }

    public interface IInterfaceSolutionUniversalEngine
    {
        void MoveObjectUp(decimal y);
        void SetObjectName(string name);
    }

    public class Sound
    {
        public Sound(string soundName, string soundFileDataPath)
        {
            SoundName = soundName;
            SoundFileDataPath = soundFileDataPath;
        }

        public string SoundName { get; private set; }
        public string SoundFileDataPath { get; private set; }
    }

    public interface IMusicPlayer
    {
        void Play(Sound sound);
    }
}

我的问题:

  1. 甚至有必要吗?如果是,什么时候?

  2. 您认为这三个中哪一个是最好的?

  3. 有更好的吗?

总而言之,我只是想从 Unity 中独立一点,但我不想马上编写新引擎。

你可以留给我最终如何设计它。(MVVM、MVC 等):)

我期待着你的回答。请成为我的英雄!

4

1 回答 1

3

我从事过这样的项目。这很棒,但也让不断地与 Unity 战斗很头疼。我们的理由是要有一个确定性游戏,并在不涉及 Unity 的情况下将其实例作为权威服务器运行。

MVC 非常适合这一点。

不久前我做了一个最小的项目。看一看。

  • 模型仅包含数据。
  • View 是一个带有 SpriteRenderers/AudioSources 的 MonoBehaviour,用于监听事件。
  • 事件是视图感兴趣的模型更改。
  • 服务是修改模型的方法的集合。
  • 模拟器勾选模型。
  • 上下文是一切开始的地方。
于 2020-01-04T15:03:11.487 回答