目录
一、效果图
二、脚本思路
1.随机方向
2.物体移动
3.墙壁检测
三、界面布局
一、效果图
二、脚本思路
1.随机方向
利用父物体旋转移动会影响其子物体的特性制作,在场景中创建三个物体一个用于移动的物体Obj,一个用于旋转的“标杆”物体 pole,一个是负责记录方向的点 Point 物体,其中Point是pole的父物体,Obj是pole父物体,界面布局如下:
当我们旋转pole的z轴时,其子物体 Point的位置方向就会改变。
脚本如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/// <summary>
/// 随机移动效果
/// </summary>
public class BaseRandomMove : MonoBehaviour
{
[Header("指针方向")]
[SerializeField] Transform pole; //标杆(负责旋转)
[SerializeField] Transform pointDis; //点位方向(物体移动方向)注意:点的位置要超出墙的包裹范围
void Start()
{
//默认隐藏标杆
pole.gameObject.SetActive(false);
RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
}
void Update()
{
//绘制线条
Debug.DrawLine(transform.position, pointDis.position, Color.red);
//按下测试
if (Input.GetKeyDown(KeyCode.A))
{
RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
}
}
#region 随机转向
/// <summary>
/// 随机方向
/// </summary>
/// <param name="min">最小值</param>
/// <param name="max">最大值</param>
/// <param name="max">旋转轴设置 不旋转 Vector3(0,0,0),所有轴旋转Vector3(1,1,1)</param>
void RandomDirection(float min, float max, Vector3 normalAngle)
{
normalAngle = new Vector3(Mathf.Clamp(normalAngle.x, 0, 1), Mathf.Clamp(normalAngle.y, 0, 1), Mathf.Clamp(normalAngle.z, 0, 1)); //旋转轴归一化
float angle = UnityEngine.Random.Range(min, max);//随机旋转
pole.localRotation = Quaternion.Euler(normalAngle * angle); //旋转标杆
}
#endregion
}
2.物体移动
获取到移动方向后直接使用 Vector3.MoveTowards来控制移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/// <summary>
/// 随机移动效果
/// </summary>
public class BaseRandomMove : MonoBehaviour
{
Vector3 originalPos; //文字原位置
[SerializeField] float speed = 3; //速度
[Header("指针方向")]
[SerializeField] Transform pole; //标杆(负责旋转)
[SerializeField] Transform pointDis; //点位方向(物体移动方向)注意:点的位置要超出墙的包裹范围
void Start()
{
//默认隐藏标杆
pole.gameObject.SetActive(false);
originalPos = transform.position; //记录原点位置
RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
}
void Update()
{
//绘制线条
Debug.DrawLine(transform.position, pointDis.position, Color.red);
transform.position = Vector3.MoveTowards(transform.position, pointDis.position, speed * Time.deltaTime);
//按下测试
if (Input.GetKeyDown(KeyCode.A))
{
RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
}
}
#region 随机转向
/// <summary>
/// 随机方向
/// </summary>
/// <param name="min">最小值</param>
/// <param name="max">最大值</param>
/// <param name="max">旋转轴设置 不旋转 Vector3(0,0,0),所有轴旋转Vector3(1,1,1)</param>
void RandomDirection(float min, float max, Vector3 normalAngle)
{
normalAngle = new Vector3(Mathf.Clamp(normalAngle.x, 0, 1), Mathf.Clamp(normalAngle.y, 0, 1), Mathf.Clamp(normalAngle.z, 0, 1)); //旋转轴归一化
float angle = UnityEngine.Random.Range(min, max);//随机旋转
pole.localRotation = Quaternion.Euler(normalAngle * angle); //旋转标杆
}
#endregion
}
3.墙壁检测
将xyz三个轴的数据使用类RestrictedDirection2数据存储。
完整脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/// <summary>
/// 范围位置
/// </summary>
[Serializable]
public class RestrictedDirection2
{
public bool isEnable = true; //true启用 false禁用
public float min;
public float max;
}
/// <summary>
/// 随机移动效果
/// </summary>
public class BaseRandomMove : MonoBehaviour
{
Vector3 originalPos; //文字原位置
[SerializeField] float speed = 3; //速度
[Header("指针方向")]
[SerializeField] Transform pole; //标杆(负责旋转)
[SerializeField] Transform pointDis; //点位方向(物体移动方向)注意:点的位置要超出墙的包裹范围
[Header("范围限制距离(LocalPosition)")]
[SerializeField] RestrictedDirection2 xPos;
[SerializeField] RestrictedDirection2 yPos;
[SerializeField] RestrictedDirection2 zPos;
void Start()
{
//默认隐藏标杆
//pole.gameObject.SetActive(false);
speed = float.Parse(ConfigFile.LoadString("CorruptionTextSpeed")); //从配置文件获取速度
originalPos = transform.position; //记录原点位置
RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
}
void Update()
{
Debug.DrawLine(transform.position, pointDis.position, Color.red);
transform.position = Vector3.MoveTowards(transform.position, pointDis.position, speed * Time.deltaTime);
CheckWall();//检测是否碰到墙壁
//按下测试
if (Input.GetKeyDown(KeyCode.A))
{
RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
}
}
#region 随机转向
/// <summary>
/// 随机方向
/// </summary>
/// <param name="min">最小值</param>
/// <param name="max">最大值</param>
/// <param name="max">旋转轴设置 不旋转 Vector3(0,0,0),所有轴旋转Vector3(1,1,1)</param>
void RandomDirection(float min, float max, Vector3 normalAngle)
{
normalAngle = new Vector3(Mathf.Clamp(normalAngle.x, 0, 1), Mathf.Clamp(normalAngle.y, 0, 1), Mathf.Clamp(normalAngle.z, 0, 1)); //旋转轴归一化
float angle = UnityEngine.Random.Range(min, max);//随机旋转
pole.localRotation = Quaternion.Euler(normalAngle * angle); //旋转标杆
}
#endregion
#region 检测是否碰到墙壁
bool isDiversion;//是否转向
bool xIsDir; //x轴是否超出距离
bool yIsDir; //y轴是否超出距离
bool zIsDir; //z轴是否超出距离
void CheckWall()
{
isDiversion = false;//是否超出距离
Vector3 newPos = transform.localPosition;
//检测轴是否超出距离
xIsDir = xPos.isEnable && (transform.localPosition.x < xPos.min || transform.localPosition.x > xPos.max);
yIsDir = yPos.isEnable && (transform.localPosition.y < yPos.min || transform.localPosition.y > yPos.max);
zIsDir = zPos.isEnable && (transform.localPosition.z < zPos.min || transform.localPosition.z > zPos.max);
isDiversion = xIsDir || yIsDir || zIsDir; //是否转向
if (xPos.isEnable)
{
if (transform.localPosition.x < xPos.min)
newPos.x = xPos.min;
if (transform.localPosition.x > xPos.max)
newPos.x = xPos.max;
}
if (yPos.isEnable)
{
if (transform.localPosition.y < yPos.min)
newPos.y = yPos.min;
if (transform.localPosition.y > yPos.max)
newPos.y = yPos.max;
}
if (zPos.isEnable)
{
if (transform.localPosition.z < zPos.min)
newPos.z = zPos.min;
if (transform.localPosition.z > zPos.max)
newPos.z = zPos.max;
}
//超出范围
if (isDiversion)
{
//设置位置不能超出范围
transform.localPosition = newPos;
RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
}
}
#endregion
}
设置成基类(为方便不同物体的操作方法重写)文章来源:https://www.toymoban.com/news/detail-615640.html
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/// <summary>
/// 范围位置
/// </summary>
[Serializable]
public class RestrictedDirection2
{
public bool isEnable = true; //true启用 false禁用
public float min;
public float max;
}
/// <summary>
/// 随机移动效果
/// </summary>
public class BaseRandomMove : MonoBehaviour
{
protected Vector3 originalPos; //文字原位置
[SerializeField] protected float speed = 3; //速度
[Header("指针方向")]
[SerializeField] protected Transform pole; //标杆(负责旋转)
[SerializeField] protected Transform pointDis; //点位方向(物体移动方向)注意:点的位置要超出墙的包裹范围
[Header("范围限制距离(LocalPosition)")]
[SerializeField] protected RestrictedDirection2 xPos;
[SerializeField] protected RestrictedDirection2 yPos;
[SerializeField] protected RestrictedDirection2 zPos;
void Start()
{
//InitData(); //初始化数据
}
void Update()
{
//MoveCheckScope(); //物体移动并检测范围
按下测试
//if (Input.GetKeyDown(KeyCode.A))
//{
// RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
//}
}
#region 初始化数据
public virtual void InitData()
{
//标杆和点位获取
if (pole == null)
pole = transform.Find("pole");
if (pointDis == null)
pointDis = pole.Find("pointDis");
//默认隐藏标杆
pole.gameObject.SetActive(false);
originalPos = transform.position; //记录原点位置
RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
}
#endregion
#region 物体移动和范围检测
protected virtual void MoveCheckScope()
{
//绘制线条
Debug.DrawLine(transform.position, pointDis.position, Color.red);
transform.position = Vector3.MoveTowards(transform.position, pointDis.position, speed * Time.deltaTime);
CheckScope();//检测是否碰到墙壁
}
#endregion
#region 随机转向
/// <summary>
/// 随机方向
/// </summary>
/// <param name="min">最小值</param>
/// <param name="max">最大值</param>
/// <param name="max">旋转轴设置 不旋转 Vector3(0,0,0),所有轴旋转Vector3(1,1,1)</param>
protected virtual void RandomDirection(float min, float max, Vector3 normalAngle)
{
normalAngle = new Vector3(Mathf.Clamp(normalAngle.x, 0, 1), Mathf.Clamp(normalAngle.y, 0, 1), Mathf.Clamp(normalAngle.z, 0, 1)); //旋转轴归一化
float angle = UnityEngine.Random.Range(min, max);//随机旋转
pole.localRotation = Quaternion.Euler(normalAngle * angle); //旋转标杆
}
#endregion
#region 检测是否碰到墙壁
bool isDiversion;//是否转向
bool xIsDir; //x轴是否超出距离
bool yIsDir; //y轴是否超出距离
bool zIsDir; //z轴是否超出距离
protected virtual void CheckScope()
{
isDiversion = false;//是否超出距离
Vector3 newPos = transform.localPosition;
//检测轴是否超出距离
xIsDir = xPos.isEnable && (transform.localPosition.x < xPos.min || transform.localPosition.x > xPos.max);
yIsDir = yPos.isEnable && (transform.localPosition.y < yPos.min || transform.localPosition.y > yPos.max);
zIsDir = zPos.isEnable && (transform.localPosition.z < zPos.min || transform.localPosition.z > zPos.max);
isDiversion = xIsDir || yIsDir || zIsDir; //是否转向
if (xPos.isEnable)
{
if (transform.localPosition.x < xPos.min)
newPos.x = xPos.min;
if (transform.localPosition.x > xPos.max)
newPos.x = xPos.max;
}
if (yPos.isEnable)
{
if (transform.localPosition.y < yPos.min)
newPos.y = yPos.min;
if (transform.localPosition.y > yPos.max)
newPos.y = yPos.max;
}
if (zPos.isEnable)
{
if (transform.localPosition.z < zPos.min)
newPos.z = zPos.min;
if (transform.localPosition.z > zPos.max)
newPos.z = zPos.max;
}
//超出范围
if (isDiversion)
{
//设置位置不能超出范围
transform.localPosition = newPos;
RandomDirection(0, 360, new Vector3(0, 0, 1)); //随机转向
}
}
#endregion
}
三、界面布局
文章来源地址https://www.toymoban.com/news/detail-615640.html
到了这里,关于Unity之物体触碰墙面后随机方向移动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!