簡體   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