Unity之物体触碰墙面后随机方向移动

这篇具有很好参考价值的文章主要介绍了Unity之物体触碰墙面后随机方向移动。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、效果图

二、脚本思路

1.随机方向

 2.物体移动

3.墙壁检测

三、界面布局

一、效果图

unity随机方向,Unity,unity,游戏引擎

二、脚本思路

1.随机方向

利用父物体旋转移动会影响其子物体的特性制作,在场景中创建三个物体一个用于移动的物体Obj,一个用于旋转的“标杆”物体 pole,一个是负责记录方向的点 Point 物体,其中Point是pole的父物体,Obj是pole父物体,界面布局如下:

unity随机方向,Unity,unity,游戏引擎

当我们旋转pole的z轴时,其子物体 Point的位置方向就会改变。

unity随机方向,Unity,unity,游戏引擎

脚本如下: 

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


}

设置成基类(为方便不同物体的操作方法重写)

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


}

三、界面布局

unity随机方向,Unity,unity,游戏引擎文章来源地址https://www.toymoban.com/news/detail-615640.html

到了这里,关于Unity之物体触碰墙面后随机方向移动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity获取物体自身坐标轴的方向以及沿着该方向运动的方法

    有时候对于一个游戏对象,需要其沿着自身的坐标轴方向进行运动,那么首先如何获取自身的坐标轴方向? 获取自身的坐标轴方向可以通过transform组件进行获取(负方向加负号即可)  Vector3 moveDirection = transform.right;  获取自身的x轴的方向  Vector3 moveDirection = transform.forward;  获

    2024年02月12日
    浏览(36)
  • Unity之用代码移动物体(平滑移动)

    因为移动的起点和终点都是不确定,所以这里用代码进行实现而不是动画(试过动画,但是发现无法成功添加clip) 物体移动常用的有两个方法,一个是Mathf.MoveTowards,一个是Mathf.Lerp,他们都用于值的平滑过渡 Mathf.MoveTowards          current:起点位置         target:目

    2024年02月07日
    浏览(28)
  • Unity点击物体后,移动到物体所在位置

    脚本挂在被点击的物体上 脚本挂在角色控制器上 改进:使用Raycast中的LayerMask 创建“cube”层 将想要被检测的物体放入该层 3.1、 3D物体事件监听 在相机上挂Physics Raycaster组件 检查是否有EventSystem 将脚本挂在被点击的物体上 添加组件Event Trigger组件 3.2、 世界UI世界监听

    2024年02月07日
    浏览(38)
  • Unity 控制物体移动

    目录 1、通过改变物体的位置使物体移动 2、通过给物体施加力使物体移动 3、移动characterController以及碰撞检测 一、相关代码展示 1、通过改变物体的位置使物体移动 2、通过给物体施加力使物体移动 3、移动characterController 以及碰撞检测 注:使用时首先要给物体添加CharacterC

    2024年02月13日
    浏览(35)
  • Unity中的物体移动

    局部坐标系(Transform.localPosition)是指当前物体相对于父物体的位置,会受到父物体的影响。 世界坐标系(Transform.Position)是指当前物体在世界空间坐标系中的位置,不受父物体影响。 若该物体有父类,则二者的关系为:该物体的世界坐标=该物体父类的世界坐标+该物体的局

    2024年02月03日
    浏览(42)
  • unity 物体移动方法

        在Unity3D中,有多种方式可以改变物体的坐标,实现移动的目的,其本质是每帧修改物体的position。     Transform 组件用于描述物体在空间中的状态,它包括 位置(position), 旋转(rotation)和 缩放(scale)。 其实所有的移动都会导致position的改变,这里所说的通过Transform组件来移

    2024年02月12日
    浏览(29)
  • unity物体移动至指定位置

    在Unity中,物体的坐标分为 局部坐标 和 世界坐标 。 局部坐标是相对于物体的父对象的坐标系,而世界坐标是相对于场景的整体坐标系。 举个例子 将下面代码挂载到Sphere上 输出结果如下 如果想让物体运动到指定的位置,通常情况下是参考世界坐标系。因为世界坐标系是整

    2024年02月05日
    浏览(35)
  • 【Unity入门】物体5种移动方法

    利用修改Transform组件的position的两种常用方法。 使用Translate()函数 直接指定新的位置 将上述两种方法在 void Update()实现每一帧物体向x方向移动1.5个单位,具体代码如下: 注意:此处1.5为啥要写1.5f,根据C#的语法规定,直接写1.5会被认为double类型的数,而这里需要flaot类

    2024年02月02日
    浏览(29)
  • unity UI 跟随3D物体移动

     

    2024年02月11日
    浏览(44)
  • Unity二维平面上物体的移动(三)

    在上一篇中使物体来回移动的函数主要是获取键盘操作输入的情况Input.GetKey(),然后物体朝着某一个方向移动gameObject.transform.Translate(Vector3.up*Time.deltaTime); 除了这个函数,可以用开发环境自带设置,Input.GetAxis(),然后使物体移动; 新建一个文件,命名为MovementOther.cs using Sys

    2024年02月08日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包