今天,我们要接着上一篇的蚂蚁线继续写行军,这次的行军主要是点击军队中的任意一个人,可以控制一整个军队都向着点击的位置移动,简单来说就是点击一个人,控制军队整体移动。
首先,要知道,我们想点击一个,但是军队里的所有人都能控制,那肯定是要判断是否为同一类才可以控制,那我这里就是用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; // 更新目标位置
}
}
效果如下:
点击一个,标签相同的全部加入集合中,右键移动就有蚂蚁线了:
一定别忘了在预制体上加标签哦: