C# Unity3d使用列表保持玩家在比赛中的位置

C# Unity3d使用列表保持玩家在比赛中的位置,c#,unity3d,C#,Unity3d,我正在创造一个简单的赛车游戏,我想保持我的球员的位置,并显示它。我认为创建一个列表,把我所有的敌人和我的球员放在里面,然后对其进行排序是很有用的,但我被困在那里了。首先,我只使用了一个敌人和我的球员。这是我到目前为止所做的代码。你知道怎么继续吗 public List<GameObject> Balls; public Text scoreText; int score; [SerializeField] GameObject myPlayer;

我正在创造一个简单的赛车游戏,我想保持我的球员的位置,并显示它。我认为创建一个列表,把我所有的敌人和我的球员放在里面,然后对其进行排序是很有用的,但我被困在那里了。首先,我只使用了一个敌人和我的球员。这是我到目前为止所做的代码。你知道怎么继续吗

public List<GameObject> Balls;
    public Text scoreText;
    int score;

    [SerializeField]
    GameObject myPlayer;

    [SerializeField]
    GameObject enemy1;

public List<GameObject> Balls;
void myList()
    {
        Balls.Add(myPlayer);
        Balls.Add(enemy1);
        Balls.Sort(CompareDistance);
    }

    private int CompareDistance(GameObject a, GameObject b)
    {
        float distance_a = a.GetComponent<GameObject>().transform.position.z;
        float distance_b = b.GetComponent<GameObject>().transform.position.z;
        if (distance_a >= distance_b)
        {
            return 1;
        }
        else
        {
            return -1;
        }
    }
公开列表;
公共文本;
智力得分;
[序列化字段]
游戏对象myPlayer;
[序列化字段]
配子体灌肠1;
公开名单;
void myList()
{
添加(myPlayer);
添加(灌肠1);
球。排序(比较);
}
私有整数比较状态(游戏对象a、游戏对象b)
{
浮动距离_a=a.GetComponent().transform.position.z;
浮动距离_b=b.GetComponent().transform.position.z;
如果(距离a>=距离b)
{
返回1;
}
其他的
{
返回-1;
}
}

<>代码>欢迎使用<代码> UnyDIS3D ,并对此进行了很好的尝试,但请考虑使用<代码>面向对象编程原则。这是很好的做法

例如,您可以首先创建一个
参与者
类,您的玩家和敌人最终都将从该类派生

public abstract class Participant : MonoBehaviour {
    //By default, the race is along the z direction
    public virtual float GetDistanceTravelled(Vector3 startPoint) {
        return startPoint.z - transform.position.z;
    }

    //At every frame, my participants shall move. How they move depends on what the player and enemy subclasses implement it.
    protected virtual void Update() {
        Move();
    }

    //Your participants will need to move, but players move with keyboard control, while enemies move programmatically. So we let the subclasses implement them.
    protected abstract void Move();
}
现在,我们创建
玩家
敌人
脚本,并将它们附加到各自的
游戏对象

public class Player : Participant {
    public override void Move() {
        //implement how you want to control your player to move
    }
}

public class Enemy : Participant { 
    public override void Move() {
        //implement how the enemies move automatically
    }
}
最后,我们需要一个类
RaceManager
来处理比赛细节的显示!您可以为此创建一个空的
GameObject
,并将此脚本附加到那里

public class RaceManager : MonoBehaviour {
    public List<Participant> participants; //you can add participants by dragging the gameobjects here from Unity's inspector, or add them in 
    public Vector3 startPoint; //again, set this in the inspector, or in Start()

    void Start() {
        //You can initialize startPoint, participants here. Or do it in the inspector
    }

    public void GetRaceDetails() {
        //Sort the list first. Check if the list is null first.. I will not do that here for clarity sake
        participants.Sort((p1, p2) => p1.GetDistanceTravelled(startPoint).Value.CompareTo(p2.GetDistanceTravelled(startPoint).Value)); //you can sort easily with lambda expressions

        //print the results here, you can iterate through the list and do a Debug.Log() or something
    }
}
public class RaceManager:monobhavior{
public List participants;//您可以通过从Unity的inspector中将游戏对象拖动到此处来添加参与者,或者将其添加到
public Vector3 startPoint;//再次在检查器或Start()中设置
void Start(){
//您可以在此处初始化startPoint,参与者。也可以在inspector中进行初始化
}
public void GetRaceDetails(){
//首先对列表排序。首先检查列表是否为空。为了清楚起见,我不会在这里这样做
参与者.Sort((p1,p2)=>p1.GetDistanceTraveled(startPoint).Value.CompareTo(p2.GetDistanceTraveled(startPoint).Value));//可以使用lambda表达式轻松排序
//在这里打印结果,您可以遍历列表并执行Debug.Log()之类的操作
}
}

您的代码非常接近,但有一些简单的错误。你的结果应该与你的排序功能相反,游戏对象不是一个组件,是一个组件容器,你已经有了引用。在这两次改变之后,你的方法似乎运行良好。我还添加了一个equals条件,以避免交换不需要交换的元素

 private int CompareDistance(GameObject a, GameObject b)
    {
        float distance_a = a.transform.position.z;
        float distance_b = b.transform.position.z;
        if (distance_a==distance_b) return 0;
        if (distance_a >= distance_b)
            return -1;  else  return 1;
    }

还要尽量避免过于频繁地创建列表,只创建一次,以后再排序,创建和填充列表可能会相对昂贵(排序也是如此)

但是我该怎么做呢?我的玩家移动脚本使用更新、开始和var声明使玩家移动,和敌人一样,这将是一个混乱。。对不起,我是c#…@MariaKodel 1的新手。可以将Start()添加到Player类中。2.外部使用的此类变量的任何示例?如果这样做有意义,请将他们移动到玩家/参与者中。3.最后,请注意,面向对象编程是一个适用于许多编码语言的好原则。通过谷歌搜索了解它的重要性和广泛应用。在学习如何编写代码时,尽早练习这一点是很好的:)嗯,好吧,在抽象类的更新中,我调用与start函数相同的player或敌人的相应更新?@MariaKodel如果只有player需要start(),那么只在player中添加它。否则,如果敌方和玩家都需要自己的Start()函数,则将其作为虚拟或抽象函数添加到参与者,然后在各自的子类(玩家/敌方)中重写它们的实现。顺便说一句,如果你打算长期(而不仅仅是这一次)进行编程,去看看什么是继承、多态、组合等,从长远来看这将对你有所帮助。你能澄清一下“保持玩家的地位”是什么意思吗