具有由附加脚本控制的脚本的Unity Control对象

时间:2020-01-08 16:23:40

标签: c# unity3d

我遵循了为自己的项目制作Tron游戏的教程,并且我想添加多人游戏功能。我已经建立了一个消息系统,其中电话将方向更改发送到显示游戏的计算机,然后使玩家更改方向。每个播放器都由附加的“移动”脚本控制,该脚本使用对自身的引用以及基于键输入的一组方法。我试图让我的游戏管理员从手机接收这些消息并引起玩家切换方向-我试图使move脚本具有静态元素,但这似乎破坏了它。

是否有一个很好的方法?还是最好编写一个新的移动脚本来同时控制所有玩家,而这些脚本只是附加在其他位置?

当前代码如下:

switch (direction)
            {
                case "N":
                    Instance.player1.GetComponent<Rigidbody2D>().velocity = Vector2.up * Move.speed;

                    break;
                case "E":
                    Instance.player1.GetComponent<Rigidbody2D>().velocity = Vector2.right * Move.speed;

                    break;
                case "S":
                    Instance.player1.GetComponent<Rigidbody2D>().velocity = Vector2.down * Move.speed;

                    break;
                case "W":
                    Instance.player1.GetComponent<Rigidbody2D>().velocity = Vector2.left * Move.speed;

                    break;

移动是对每个游戏附带的脚本的引用,但是要使脚本起作用,每次更改方向后都需要对此方法进行调用:

public void spawnWall()
{
    lastWallEnd = transform.position;
    GameObject objectOfGame = (GameObject)Instantiate(wallPrefab, transform.position, Quaternion.identity);
    wall = objectOfGame.GetComponent<Collider2D>();
}

我试图将其设置为静态,但无法正常工作,因此我猜测这不是采取的方法。每次进行内部方向更改时,都会调用SpawnWall。

void createConstantWall(Collider2D collision, Vector2 start, Vector2 finish)
{
    collision.transform.position = start + (finish - start) * 0.5f;
    float distance = Vector2.Distance(start, finish);
    if (start.x != finish.x)
        collision.transform.localScale = new Vector2(distance + 1, 1);
    else
        collision.transform.localScale = new Vector2(1, distance + 1);
}

此功能在更新中被调用

丢失方法:

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision != wall)
    {
        //add losing stuff
        Destroy(gameObject);
    }
}

1 个答案:

答案 0 :(得分:1)

有几种方法可以处理来自不同电话(或其他来源)的多个用户输入。这是我的首选解决方案:

  • 每当发送动作时,所有输入都会通过具有玩家ID的通用管理器进行。此输入将转换为事件以简化依赖关系。

由于您已经声明自己已经将一条包含玩家编号和方向的自定义消息发送给游戏管理员,因此我们将予以处理。

在GameManager.cs或InputManager.cs之内

public static event Action<int, string> OnInputReceived;

void InputReceived(int playerNumber, string direction)
{
    OnInputReceived?.Invoke(playerNumber, direction);
}

在应该附加到游戏中每个单独玩家的PlayerMovementController.cs中,您应该跟踪您的玩家编号,或者能够检查另一个附加的脚本来查找玩家编号:

public int playerId;

void Awake()
{
    GameManager.OnInputReceived += MovePlayer;
}

void MovePlayer(int inputPlayerId, string direction)
{
    if(inputPlayerId != playerId)
        return;
    else
    {
        //move THIS player in the "direction" using your movement logic
    }
}

void OnDestroy()
{
    GameManager.OnInputReceived -= MovePlayer;
}

如果您所有的播放器都有唯一的ID并附加了PlayerMovementController,则他们现在都可以收听所有输入,但只有在其ID绑定在一起时才移动。如果您的GameManager调用InputReceived(1,“ E”),则所有的PlayerMovementControllers都将调用MovePlayer(1,“ E”),但是只有playerId == 1的那个才会移动,因为其他所有的都立即返回。

-免责声明:所有这些代码都是在StackOverflow中自由编写的,因此可能存在一些我没有发现的语法错误。请让我知道或直接编辑。

相关问题