将 Unity C# 代码与 "normal" C# 代码分开
Separating Unity C# code from "normal" C# code
我考虑过将 Unity C# 代码(我只能使用 UnityEngine 的代码)与 "normal" C# 代码(int x = 3; bool isKnockMeDead = true; void KnockMeDead();
等)
分开
为什么?这样我就可以(例如)从 Unity 切换到 Wpf,而不必重写整个逻辑。所以我的 EngineObject 是 Window 而不是 MonoBehviour...
这个问题我已经有了一些解决方案:
但我对其中任何一个都不是 100% 满意,因为...
第一个解决方案 - InheritanceSolution.cs
这是最快的方法,但是您没有 100% 的视觉分离,并且还给出了在 Child class 中使用 Unity 代码的危险。
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
如果几个人想在一个 class 上工作而不被打扰 and/or 如果自动生成的代码应该与用户分开,则实际使用关键字。
我只是用它来分隔代码,这还可以,但是不能用来说每个class有200行,因为它只是保持一个class以上编译时。
问题来了 :/
视觉分离会很完美,但实现没有任何变化,我仍然可以在两个(一个)中使用 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 请分开 class 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);
}
}
我的问题:
有必要吗?如果是,什么时候?
你认为这三个中哪个最好?
还有更好的吗?
综上所述,我只是想稍微独立于Unity,但我不想马上编写新引擎。
最后应该怎么设计就交给我吧。 (MVVM、MVC 等):)
期待您的回答。
请成为我的英雄!
我做过这样的项目。这很棒,但也很头疼不断与 Unity 打交道。我们的原因是要有一个确定性的游戏和 运行 它的一个实例作为权威服务器,而不需要 Unity 参与。
MVC 非常适合这个。
我刚才做了 minimal project。看看。
- 模型仅包含数据。
- View 是一个具有 SpriteRenderers/AudioSources 的 MonoBehaviour,用于侦听事件。
- 事件是视图感兴趣的模型更改。
- 服务是修改模型的方法的集合。
- 模拟器勾选模型。
- 上下文是一切的开始。
我考虑过将 Unity C# 代码(我只能使用 UnityEngine 的代码)与 "normal" C# 代码(int x = 3; bool isKnockMeDead = true; void KnockMeDead();
等)
为什么?这样我就可以(例如)从 Unity 切换到 Wpf,而不必重写整个逻辑。所以我的 EngineObject 是 Window 而不是 MonoBehviour...
这个问题我已经有了一些解决方案:
但我对其中任何一个都不是 100% 满意,因为...
第一个解决方案 - InheritanceSolution.cs
这是最快的方法,但是您没有 100% 的视觉分离,并且还给出了在 Child class 中使用 Unity 代码的危险。
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
如果几个人想在一个 class 上工作而不被打扰 and/or 如果自动生成的代码应该与用户分开,则实际使用关键字。
我只是用它来分隔代码,这还可以,但是不能用来说每个class有200行,因为它只是保持一个class以上编译时。
问题来了 :/
视觉分离会很完美,但实现没有任何变化,我仍然可以在两个(一个)中使用 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 请分开 class 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);
}
}
我的问题:
有必要吗?如果是,什么时候?
你认为这三个中哪个最好?
还有更好的吗?
综上所述,我只是想稍微独立于Unity,但我不想马上编写新引擎。
最后应该怎么设计就交给我吧。 (MVVM、MVC 等):)
期待您的回答。 请成为我的英雄!
我做过这样的项目。这很棒,但也很头疼不断与 Unity 打交道。我们的原因是要有一个确定性的游戏和 运行 它的一个实例作为权威服务器,而不需要 Unity 参与。
MVC 非常适合这个。
我刚才做了 minimal project。看看。
- 模型仅包含数据。
- View 是一个具有 SpriteRenderers/AudioSources 的 MonoBehaviour,用于侦听事件。
- 事件是视图感兴趣的模型更改。
- 服务是修改模型的方法的集合。
- 模拟器勾选模型。
- 上下文是一切的开始。