繁体   English   中英

将 Unity C# 代码与“普通”C# 代码分开

[英]Separating Unity C# code from "normal" C# code

我曾想过将 Unity C# 代码(我只能与使用 UnityEngine 一起使用的代码)与“普通”C# 代码( int x = 3; bool isKnockMeDead = true; void KnockMeDead();等) 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 等):)

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

我曾参与过这样的项目。 这很棒,但也很头疼不断与 Unity 战斗。 我们的原因是拥有一个确定性游戏,并在不让 Unity 参与的情况下将其实例作为权威服务器运行。

MVC 非常适合这一点。

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

  • 模型仅包含数据。
  • View 是一个 MonoBehaviour,带有 SpriteRenderers/AudioSources 来监听事件。
  • 事件是视图感兴趣的模型更改。
  • 服务是修改模型的方法的集合。
  • 模拟器勾选模型。
  • 上下文是一切开始的地方。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM