unity 中实现 rts 游戏对士兵的选择和移动

发布时间 2023-09-24 14:16:36作者: qi_8080

playerController 部分用来处理玩家鼠标对场景内元素交互的逻辑

代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class PlayerController : MonoBehaviour
{
    //场景中的士兵角色列表
    public GameObject[] selectedArray;

    // Start is called before the first frame update
    void Start()
    {
        //获得场景中的士兵角色对象并存到我们的selectedArray中
        selectedArray = GameObject.FindGameObjectsWithTag("soldier");
    }

   
    void Update()
    {
        CameraRadiographicTesting();
    }

    /// <summary>
    /// 鼠标点击发出射线。
    /// </summary>
    private void CameraRadiographicTesting()
    {
        //鼠标右键
        if (Input.GetMouseButton(1))
        {
            //射线检测
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            bool isCollider = Physics.Raycast(ray, out hit);
            if (isCollider)
            {
                for (int i = 0; i < selectedArray.Length; i++)
                {
                    if (selectedArray[i].GetComponent<SoldierController>().GetSelected())
                    {
                        //为选中的士兵设置移动目标
                        selectedArray[i].GetComponent<NavMeshAgent>().SetDestination(hit.point);
                    }
                }
            }
        }
        //鼠标左键
        if (Input.GetMouseButton(0))
        {
            //将之前选择的角色设置为非选中状态
            GameObject[] allSolierGameObj = GameObject.FindGameObjectsWithTag("soldier");
            for (int i = 0; i < allSolierGameObj.Length; i++)
            {
                allSolierGameObj[i].GetComponent<SoldierController>().SetSelected(false);
            }
            //射线检测
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            bool isCollider = Physics.Raycast(ray, out hit);
            if (isCollider)
            {
                //获得检测到物体的GameObject
                SoldierController hitStatus = hit.collider.gameObject.GetComponent<SoldierController>();
                if (hitStatus != null)
                {
                    //通过自己封装的SetSelected函数设置士兵脚本中的selected的值
                    hitStatus.SetSelected(true);
                }
            }



        }

    }
}

SoldierController 用来处理士兵对操作的相应

代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class SoldierController : MonoBehaviour
{
    //当前角色是否被选择
    private bool Selected = false;
    //角色Ai导航
    private NavMeshAgent agent;
    //角色动画控制器
    private Animator soldierAnimator;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        soldierAnimator = GetComponentInChildren<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        SoldierAnimationController();
        SoldierAnimationController();
    }

    //设置角色是否被选择
    public void SetSelected(bool Selected)
    {
        this.Selected = Selected;
    }

    //获得角色是否被选中的信息
    public bool GetSelected()
    {
        return this.Selected;
    }
    //角色移动
    public void MoveTo(Vector3 position)
    {
        if (position != null)
        {
            agent.SetDestination(position);

        }
    }

    //角色的移动动画实现
    void SoldierAnimationController()
    {
        Vector3 forward = transform.forward;
        Vector3 right = transform.right;
        float forwardSpeed = Vector3.Dot(forward, agent.velocity);
        float rightSpeed = Vector3.Dot(right, agent.velocity);
        soldierAnimator.SetFloat("speed", forwardSpeed);
        soldierAnimator.SetFloat("direction", rightSpeed);
    }

}