C# 如何在游戏对象中添加多个脚本

C# 如何在游戏对象中添加多个脚本,c#,unity3d,C#,Unity3d,我的团结计划正在发展,我有点害怕 我已经创建了一个播放器,它有大量的脚本在一起工作。(最近会更大。) 这就是它的样子 播放器的所有脚本都是从一个基本脚本继承而来的,该脚本只包含一些受保护的静态变量,这些变量可以从所有其他脚本更改,因此我可以从任何单个脚本检查播放器的任何状态 其中一些: public class BasicCharacter : MonoBehaviour { protected static Rigidbody2D rb2d; protected static

我的团结计划正在发展,我有点害怕

我已经创建了一个播放器,它有大量的脚本在一起工作。(最近会更大。) 这就是它的样子

播放器的所有脚本都是从一个基本脚本继承而来的,该脚本只包含一些受保护的静态变量,这些变量可以从所有其他脚本更改,因此我可以从任何单个脚本检查播放器的任何状态

其中一些:

public class BasicCharacter : MonoBehaviour
{
    protected static Rigidbody2D rb2d;
    protected static CharacterRenderer characterRenderer;
    protected static Vector2 directionLookingAt;
    protected static Vector2 movement;
    protected static Vector2 attackPos;

    protected static bool hasDashedAttack = false;
    protected static bool hasFinalizerAttack = false;
    protected static bool isUsingMovementSkills = false;
    protected static bool isStringingAttacks = false;
    ...
这是我如何调用其中一些变量作为条件来执行其他一些操作的示例:

private GameObject GetAttackAnimation()
    {
        if(hasFinalizerAttack)
        {
            return empoweredAttackVFX;
        }
        else if (hasDashedAttack)
        {
            return dashedAttackVFX;
        }
        else if (isAttackCharged)
        {
            return chargedAttackVFX;
        }
        return basicAttackVFX;
    }
我担心的是,我觉得我在这里做得不干净、不好。我认为这是一个更好的方式来面对这个问题。在我的代码中,在引入新的游戏机制之前,我必须记住玩家可能处于的每一种状态

我有几个问题:

我需要一个跟踪可能行为的玩家管理员吗

有没有办法不把每个脚本都添加到游戏对象中,让它看起来更干净


基本角色脚本是可持续的吗?

使用ScriptableObjects()可以使角色的某些部分更加模块化,它们不一定会降低复杂性(游戏很复杂,你必须接受这一点)但它们至少可以帮助你消除玩家控制器的混乱,并将你的功能扩展到不同的更独立的类中,这些类可以方便地内置到Unity的编辑器中,允许你拖放它们,更重要的是,可以将它们与主玩家预置分开进行编辑,允许您避免“庞大的脚本数据墙”问题

例如,在本例中,我将把能力数据和buff/malus数据分离为ScriptableObjects。你可以在那里设置你想要的任何等级,并将它们作为独立的游戏资产修改到你的核心玩家(如果你投入足够的精力,你甚至可以使它们模块化,足以为敌人和你的玩家工作,这非常方便!)

一旦设置了scriptableobjects,就可以为它们提供一些基本功能,如“OnTick”、“OnTakeDamage”、“OnActivate”等,甚至还有一些内部状态,如“IsSkillActive”等,然后将它们存储为播放器对象上的列表或字典,并对它们进行迭代。快速伪代码可以是:

bool canInput = true;
foreach(Ability in Abilities)
{
 if (Ability.IsSkillActive())
 {
  canInput = false; //still in the middle of an active ability
  break;
 }
}
if (canInput)
{
 //Do allow player to have input here.
}
或者你可以:

class DamageOverTimeDebuff : ScriptableObject
{
 int damagePerTick = 1;

 OnTick(PlayerObject afflictedPlayer)
 {
  afflictedPlayer.TakeDamage(1);
 }
}
通过这种方式,您可以使能力和效果更加模块化,并通过组合构建您的玩家,而不是针对每个场景使用if语句

这就是说,有一个折衷,这增加了您的抽象级别,这使得非常具体的行为或特殊的边缘情况更难实现。你也可能会花很多时间为你的减益或只用于一种效果的能力编写特定的函数,在这种情况下,这只是额外的工作


这只是一种可能的策略,你所描述的问题是每一场比赛都必须面对并以不同的方式处理。也许ScriptableObjects可以帮助你将你的功能分解成更简单的东西,也许它们只是一个额外的样板文件,妨碍了你的工作。这取决于游戏的具体需求。

你不应该使用
静态变量来实现这一点。。。如果你改变主意,想要两个玩家或者两个行为相似的对象,那该怎么办?@Empty给出了一个很好的答案,但另一种减少混乱的方法是“部分”类。这允许您让您的播放器控制器具有所有必需的代码,但您可以为各自的功能创建完整的代码文件。例如,在我正在开发的一个游戏中,我有一个用于输入处理的文件,另一个用于动画,另一个用于移动,因为所有这些东西加在一起将创建一个巨大的代码块。这是一个非常有趣的东西。我来看看。我不认为我做错了事情,但不是以更好的方式。我已经在OOP中编写代码好几年了,没有完全模块化和受控的感觉让我担心。我在unity是新手,我只需要知道这些事情是如何正确完成的。顺便说一句,回答得很好。谢谢。