为每个对象的行为创建脚本,而不是在对象脚本主体中编写所有内容

Posted

技术标签:

【中文标题】为每个对象的行为创建脚本,而不是在对象脚本主体中编写所有内容【英文标题】:Creating scripts for each objects behaviours instead of writing everything in the object script body 【发布时间】:2019-09-12 12:07:12 【问题描述】:

我的示例场景中有两个游戏对象。两者都需要在其本地空间上以特定速度不断旋转。它们只是简单的硬币,目的是由玩家收集。我没有在每个 Update() 方法中编写旋转脚本,而是创建了一个名为 Rotator 的脚本,它使它附加到的对象实际旋转。

我已将组件 Rotator 附加到每个对象,它工作得很好。 现在我有两个游戏对象,它们有一个名为 Rotator 的组件,可以让它们旋转。

这是 Rotator 类:

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 脚本附加到它。 在最后一种情况下,我将拥有一个包含两个组件的游戏对象:

播放器控制器 旋转器

当然,这只是一个例子,我不希望我的玩家一直在自欺欺人,只是为了说明我的观点。

所以,最后,我需要了解这是否是一个好习惯,即使像旋转这样的一小行代码值得创建一个组件?而且我指的是多个对象所需的行为,当然,我知道如果它是一个唯一的情况,直接在已经附加到游戏对象的脚本中编写它更有意义问题。

很长的帖子,希望我说的足够清楚。谢谢大家!

【问题讨论】:

本视频可能对您有所帮助:youtube.com/watch?v=8TIkManpEu4我不是该视频的创作者,但他谈到了在 Unity 中进行组合与继承的优势,感觉就像您在这里所问的。 【参考方案1】:

你做它的方式就是它应该做的方式。统一的想法是使用可以重复使用的小型模块化组件。然而,拥有大量更新函数可能会对性能产生影响,尤其是如果您使用 Mono 而不是 IL2CPP。

但是对此有多种解决方案。

使用 IL2CPP 删除 C#(您的代码)和 c++ 端(引擎代码)之间的“虚拟”调用层。 编写一个从 c# 端更新所有脚本的行为管理器。 查看实体组件系统并迭代所有需要在一个“更新函数”中旋转的内容。

我们实际上发布了一款旋转水晶会影响 CPU 性能的游戏。最后,我们每帧只计算一次 LocalRotation 值,并将其分配给所有晶体。

【讨论】:

我是 Unity 的新手,您列出的概念对我来说仍然太高级,但我肯定会保存这个答案以备后用。谢谢!【参考方案2】:

这实际上取决于游戏的大小和附加的脚本数量。如果这是一个包含几十个长脚本的大型游戏,你必须在游戏的组织和性能之间取得平衡,因为两者都很重要。例如,在一个 Update 方法中调用一个方法 1000 次要比在一个 Update 方法中调用 1000 个单独的脚本更好 在您的情况下,由于它很简单并且两个对象的旋转相同,因此最好像您一样创建一个通用的单独脚本。如果您需要对它们的轮换进行任何更改,您只需更改一次即可,而且不会显着降低性能成本。

【讨论】:

没错,这确实是 Unity 的构建方式吗?所有关于添加以提供功能的组件...我对这个主题很陌生,所以我只是确保从一开始就正确理解。

以上是关于为每个对象的行为创建脚本,而不是在对象脚本主体中编写所有内容的主要内容,如果未能解决你的问题,请参考以下文章

yii2.0框架关键概念

Visual Studio 数据库项目能否为每个已更改的对象创建单独的差异脚本?

我用 php 创建了一个脚本来将 xml 转换为 csv,但是所有结果都是垂直的,而不是在一行中带有标题

在主体树中执行脚本时 DOM 准备好了吗?

Blender:通过脚本创建自定义物理

Unity脚本生命周期与执行顺序