为每个对象行为创建脚本,而不是在对象脚本主体中编写所有内容
Creating scripts for each objects behaviours instead of writing everything in the object script body
我的示例场景中有两个游戏对象。两者都需要在本地 space 上以特定速度不断 旋转 。它们只是简单的 硬币 ,其目的是供玩家收集。我没有在每个 Update() 方法中编写旋转脚本,而是创建了一个名为 Rotator 的脚本,使它所附加的对象实际旋转。
我已经将组件 Rotator 附加到每个对象,它工作得很好。
现在我有两个游戏对象,它们有一个名为 Rotator 的组件,可以使它们旋转。
这是旋转器 class:
using UnityEngine;
public class Rotator : MonoBehaviour
{
[SerializeField][Range(5, 10)]
private int _rotationSpeed = 5;
[SerializeField]
private float _xAxes = 0;
[SerializeField]
private float _yAxes = 0;
[SerializeField]
private float _zAxes = 0;
void Update()
{
transform.Rotate(new Vector3(_xAxes, _yAxes, _zAxes) * _rotationSpeed * Time.deltaTime);
}
}
我认为通过这种方式,我的游戏对象的创建流程比在每个应该旋转的元素中编写上面相同的代码更容易模块化。
我的问题是:这会对性能产生影响吗?将行为拆分成小块或组件然后将它们添加到需要它们的每个游戏对象中是不是一个坏主意?或者,在只是简单旋转的情况下,直接在一个游戏对象脚本中编写该行代码更好?
例如,我现在有另一个名为 Player 的游戏对象,它也需要在自己身上旋转。这个游戏对象已经附加了另一个名为 PlayerController 的脚本,它通过键盘输入处理玩家的移动。我可以写这部分...
transform.Rotate(new Vector3(_xAxes, _yAxes, _zAxes) * _rotationSpeed * Time.deltaTime);
...在 PlayerController 的 update() 方法中,或者,就像我认为更好的那样,将 Rotator 脚本附加到它。
在最后一种情况下,我将有一个包含两个组件的游戏对象:
- 播放器控制器
- 旋转器
当然,这只是一个例子,我不希望我的播放器真的一直在自己身上旋转,只是为了说明我的观点。
所以,最后,我需要了解这是否是一个好的做法,即使像旋转这样的一小行代码也值得创建一个分量?我指的是不止一个对象需要的行为,当然,我知道如果它是唯一的情况,那么直接将它写在已经附加到游戏对象的脚本中更有意义问题。
长post,希望我已经足够清楚了。谢谢大家!
这真的取决于游戏的大小和附加的脚本数量。如果这是一款包含数十个长脚本的大型游戏,您必须在游戏组织和性能之间取得平衡,因为两者都很重要。例如,在一个 Update 方法中调用一个方法 1000 次比使用一个 Update 方法调用 1000 个单独的脚本要好
在您的情况下,因为它很简单并且两个对象的旋转相同,所以最好像您一样创建一个通用的单独脚本。如果您需要对他们的轮换进行任何更改,您只需更改一次,而且不会对性能造成重大影响。
你做事的方式就是它应该做的方式。统一的思想是使用可以重复使用的小型模块化组件。然而,拥有大量更新函数会对性能产生影响,尤其是当您使用 Mono 而不是 IL2CPP 时。
但是有多种解决方案。
- 使用 IL2CPP 删除 C#(您的代码)和 C++ 端(引擎代码)之间的 "virtual" 调用层。
- 编写一个行为管理器,从 C# 端更新您的所有脚本。
- 查看实体组件系统并遍历所有需要轮换的东西 "Update function"。
我们实际上发布了一款游戏,其中旋转水晶具有 CPU 性能影响。最后我们每帧只计算一次LocalRotation值,并分发给所有的晶体。
我的示例场景中有两个游戏对象。两者都需要在本地 space 上以特定速度不断 旋转 。它们只是简单的 硬币 ,其目的是供玩家收集。我没有在每个 Update() 方法中编写旋转脚本,而是创建了一个名为 Rotator 的脚本,使它所附加的对象实际旋转。
我已经将组件 Rotator 附加到每个对象,它工作得很好。 现在我有两个游戏对象,它们有一个名为 Rotator 的组件,可以使它们旋转。
这是旋转器 class:
using UnityEngine;
public class Rotator : MonoBehaviour
{
[SerializeField][Range(5, 10)]
private int _rotationSpeed = 5;
[SerializeField]
private float _xAxes = 0;
[SerializeField]
private float _yAxes = 0;
[SerializeField]
private float _zAxes = 0;
void Update()
{
transform.Rotate(new Vector3(_xAxes, _yAxes, _zAxes) * _rotationSpeed * Time.deltaTime);
}
}
我认为通过这种方式,我的游戏对象的创建流程比在每个应该旋转的元素中编写上面相同的代码更容易模块化。
我的问题是:这会对性能产生影响吗?将行为拆分成小块或组件然后将它们添加到需要它们的每个游戏对象中是不是一个坏主意?或者,在只是简单旋转的情况下,直接在一个游戏对象脚本中编写该行代码更好?
例如,我现在有另一个名为 Player 的游戏对象,它也需要在自己身上旋转。这个游戏对象已经附加了另一个名为 PlayerController 的脚本,它通过键盘输入处理玩家的移动。我可以写这部分...
transform.Rotate(new Vector3(_xAxes, _yAxes, _zAxes) * _rotationSpeed * Time.deltaTime);
...在 PlayerController 的 update() 方法中,或者,就像我认为更好的那样,将 Rotator 脚本附加到它。 在最后一种情况下,我将有一个包含两个组件的游戏对象:
- 播放器控制器
- 旋转器
当然,这只是一个例子,我不希望我的播放器真的一直在自己身上旋转,只是为了说明我的观点。
所以,最后,我需要了解这是否是一个好的做法,即使像旋转这样的一小行代码也值得创建一个分量?我指的是不止一个对象需要的行为,当然,我知道如果它是唯一的情况,那么直接将它写在已经附加到游戏对象的脚本中更有意义问题。
长post,希望我已经足够清楚了。谢谢大家!
这真的取决于游戏的大小和附加的脚本数量。如果这是一款包含数十个长脚本的大型游戏,您必须在游戏组织和性能之间取得平衡,因为两者都很重要。例如,在一个 Update 方法中调用一个方法 1000 次比使用一个 Update 方法调用 1000 个单独的脚本要好
在您的情况下,因为它很简单并且两个对象的旋转相同,所以最好像您一样创建一个通用的单独脚本。如果您需要对他们的轮换进行任何更改,您只需更改一次,而且不会对性能造成重大影响。
你做事的方式就是它应该做的方式。统一的思想是使用可以重复使用的小型模块化组件。然而,拥有大量更新函数会对性能产生影响,尤其是当您使用 Mono 而不是 IL2CPP 时。
但是有多种解决方案。
- 使用 IL2CPP 删除 C#(您的代码)和 C++ 端(引擎代码)之间的 "virtual" 调用层。
- 编写一个行为管理器,从 C# 端更新您的所有脚本。
- 查看实体组件系统并遍历所有需要轮换的东西 "Update function"。
我们实际上发布了一款游戏,其中旋转水晶具有 CPU 性能影响。最后我们每帧只计算一次LocalRotation值,并分发给所有的晶体。