Unity——行军

  今天,我们要接着上一篇的蚂蚁线继续写行军,这次的行军主要是点击军队中的任意一个人,可以控制一整个军队都向着点击的位置移动,简单来说就是点击一个人,控制军队整体移动。

  首先,要知道,我们想点击一个,但是军队里的所有人都能控制,那肯定是要判断是否为同一类才可以控制,那我这里就是用Tag标签来判断是否为同一类,然后加入一个集合统一控制所有游戏对象移动,移动可以使用Lerp函数,也可以使用DoTween,还可以使用导航移动,这里我用的就是导航移动。

  那现在大致思路知道了,理解了的宝宝们可以先自己尝试一下,顺着这个思路自己尝试一下,理解的比较慢的宝宝可以看一下我是怎么写的,试着边敲便理解哦。

  代码如下:

  首先创建RoleMgr实例化多个游戏对象,这里我是把Cube放到Resources旗下变成预制体使用,记得要给Cube身上动态添加Player脚本,并且手动加上NavMeshAgent导航,地板Plane静态烘焙一下哦:

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

public class RoleMgr : MonoBehaviour
{
    GameObject player;
    public Transform player_pos, enemy_pos;

    // Start is called before the first frame update
    void Start()
    {
        for (int i = 0; i < 5; i++)
        {
            player = Instantiate(Resources.Load<GameObject>("Role/Player"));
            Vector3 pos = Random.insideUnitCircle * 5f;
            player.transform.position = player_pos.position + new Vector3(pos.x, 0, pos.y); 
            player.AddComponent<Player>();
        }
    }
}

 Player脚本主要就是写获取角色身上的NavMeshAgent组件,写一个方法MoveToPosition来控制导航移动到的目标位置:

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

public class Player : MonoBehaviour
{
    public float moveSpeed = 5;
    public NavMeshAgent nav;

    private void Start()
    {
        nav = GetComponent<NavMeshAgent>();
    }

    public void MoveToPosition(Vector3 targetPosition)
    {
        nav.SetDestination(targetPosition);
    }
}

  现在,我们该创建一个ArmyMgr军队管理类的脚本,鼠标左键选择游戏对象,右键射线点击目标位置:

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

public class ArmyMgr : MonoBehaviour
{
    public List<Player> players_army = new List<Player>();
    public Player selectplayer;
    public Vector3 targetPos;
    public GameObject lin;
    public static ArmyMgr ins;

    private void Awake()
    {
        ins = this;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            SelectPlayer();
            lin.gameObject.SetActive(true);
        }

        //右键移动这个军队
        if(Input.GetMouseButton(1) && selectplayer != null)
        {
            MoveArmy();
        }
    }

    private void MoveArmy()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out RaycastHit hit))
        {
            targetPos = hit.point;
            Lin.ins.UpdateTargetPosition(targetPos);
            foreach (var item in players_army)
            {
                item.MoveToPosition(targetPos);
            }
        }
    }

    private void SelectPlayer()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if(Physics.Raycast(ray, out RaycastHit hit))
        {
            Player player = hit.collider.GetComponent<Player>();
            if (player != null)
            {
                selectplayer = player; //保存当前选中的角色
                players_army.Clear();
                string playertag = player.gameObject.tag;
                GameObject[] playerwithsametag = GameObject.FindGameObjectsWithTag(playertag);
                foreach (var item in playerwithsametag)
                {
                    Player armyplayer = item.GetComponent<Player>();
                    if(armyplayer != null)
                    {
                        players_army.Add(armyplayer);
                    }
                }
            }
        }
    }
}

这里选择和整体移动就写好了,我们要行走的时候搭配上蚂蚁线,代码就要稍微改动蚂蚁线的起始点和终点,代码如下:

using System.Collections;
using System.Collections.Generic;
using System.Runtime.ConstrainedExecution;
using UnityEngine;
using static TMPro.SpriteAssetUtilities.TexturePacker_JsonArray;

public class Lin : MonoBehaviour
{
    LineRenderer line;
    Material material;
    Vector2 offset;
    int mainTexProperty;
    //用于控制偏移的时间
    float time = 0;
    // 降低偏移频率,使偏移更平滑
    float frequency = 0.05f;
    // 降低偏移速度,使偏移更平滑
    float moveSpeed = 0.05f;

    public Transform selectposition;
    public Vector3 targetPos;
    public static Lin ins;

    private void Awake()
    {
        ins = this;
    }

    // Start is called before the first frame update
    void Start()
    {
        //获取LineRenderer组件
        line = GetComponent<LineRenderer>();
        //获取材质的主纹理属性
        mainTexProperty = Shader.PropertyToID("_MainTex");
        //获取LineRenderer材质
        material = line.material;
        //设置起点和终点
        
        if (selectposition != null)
        {
            line.SetPosition(0, selectposition.position);
        }
    }
    void Update()
    {
        if (ArmyMgr.ins.selectplayer != null)
        {
            selectposition = ArmyMgr.ins.selectplayer.transform;
        }
        // 更新终点  
        line.SetPosition(1, targetPos); // 将终点设置为目标位置  
        //獫鵺喝累加时间
        time += Time.deltaTime;
        //当时间超过频率时
        if (time >= frequency)
        {
            time = 0;
            offset = new Vector2(moveSpeed, 0);
            //设置材质的新偏移
            material.SetTextureOffset(mainTexProperty, offset);
        }

        if (selectposition != null)
        {
            line.SetPosition(0,selectposition.position);
        }
    }
    // 更新目标位置的方法  
    public void UpdateTargetPosition(Vector3 newPosition)
    {
        targetPos = newPosition; // 更新目标位置  
    }
}

效果如下:

  点击一个,标签相同的全部加入集合中,右键移动就有蚂蚁线了:

一定别忘了在预制体上加标签哦:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值