unity物体移动至指定位置

物体坐标与物体移动

  • 世界坐标与局部坐标之间的转换
  • 物体移动至指定位置
    • 需求
    • 思路
    • 注意

世界坐标与局部坐标之间的转换

在Unity中,物体的坐标分为局部坐标世界坐标
局部坐标是相对于物体的父对象的坐标系,而世界坐标是相对于场景的整体坐标系。

使用transform.position属性来获取物体在世界坐标系下的坐标。
使用transform.localPosition属性来获取物体在世界坐标系下的坐标。
使用transform.TransformPoint将局部坐标系转换为世界坐标系。
使用transform.InverseTransformPoint世界坐标系转换为局部坐标系。

举个例子
unity物体移动至指定位置_第1张图片

unity物体移动至指定位置_第2张图片
将下面代码挂载到Sphere上

public class Coordinate : MonoBehaviour
{
    public GameObject SomeThing;
    public Vector3 SomePoint;

    void Start()
    {
        Debug.Log("世界坐标:" + transform.position);
        Debug.Log("局部坐标:" + transform.localPosition);

        Debug.Log("当前坐标:" + SomePoint);
        Vector3 worldPoint = transform.TransformPoint(SomePoint);
        Debug.Log("局部坐标转为世界坐标:" + worldPoint);
        Vector3 localPoint = transform.InverseTransformPoint(worldPoint);
        Debug.Log("世界坐标转为局部坐标:" + localPoint);
    }
}

输出结果如下
unity物体移动至指定位置_第3张图片

如果想让物体运动到指定的位置,通常情况下是参考世界坐标系。因为世界坐标系是整个场景的坐标系,而局部坐标系是相对于物体的父对象的坐标系。假设想让物体移动到坐标为(x,y,z)的位置,参照世界坐标与局部坐标的物体运动代码如下:

// 世界坐标下运动
transform.position = new Vector3(x, y, z);
// 局部坐标下运动
transform.localPosition = new Vector3(x, y, z);

如果想要实现多个物体以相同的速度按照顺序移动到不同的位置,可以参考下一节。

物体移动至指定位置

需求

将一个由多个零部件组成的自定义模型导入unity中,希望实现该模型的部分拆卸过程。下面以共有11个拆卸步骤为例

思路

在网上找了很多资料,目前想到的办法有利用协程或动画播放的方法(这里只做了协程的方法,动画的等我学会再加上)
1、首先是自定义的模型的拆卸,因此需要知道哪些零部件需要先拆,哪些后拆。
2、还需要考虑碰撞等干涉情况,因此下面代码中有的零部件出现了多次。
3、将所有需要拆卸的零部件创建一个空父对象,下面这个代码就挂载到空父对象上。
4、利用GameObject.Find()函数,找到每个零部件,并放在一个数组里面,便于后续对每个零部件进行操作。
5、将每个零部件需要移动的指定位置与运动时间,同样放在另外两个数组里面。
6、零部件的移动,我使用的是DOTween插件中的DOLocalMove方法。

DOTween插件解析

注意

下面代码有待完善,如“每一步拆卸步骤所有的时间是不一样的,但速度应该是一样,这个我目前还不知道如何解决,只知道运动的位移相同的零件,其运动速度是一样的”
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class MoveTogether : MonoBehaviour
{
    //物体数组
    public GameObject[] objects;
    //物体名称数组
    public string[] Names;
    //目标位置数组
    public Vector3[] targetPositions;
    //运动时间数组
    public float[] moveTime;
    void Start()
    {
        Names = new string[]
        { 
            "一移动螺丝", 
            "一移动螺丝", 
            "中间部分", 
            "铁片1螺丝",
            "铁片1",
            "铁片2螺丝",
            "铁片2",
            "铁片3螺丝",
            "铁片3",
            "整体下方", 
            "整体下方" };

        objects = new GameObject[Names.Length];
        for (int i = 0; i < Names.Length; i++)
        {
            objects[i] = GameObject.Find(Names[i]);
        }
        
        targetPositions = new Vector3[] 
        { new Vector3(0f, 0f, -0.5f),  //一移动螺丝向下
          new Vector3(3f, 0f, -0.5f),  //一移动螺丝向右
          new Vector3(0f, 0f, -0.8f), //中间部分向下
          new Vector3(3f, 0f, 0f),    //铁片1螺丝向外
          new Vector3(3f, 0f, 0f),    //铁片1向外
          new Vector3(0f, -2f, 0f),  //铁片2螺丝向外
          new Vector3(0f, -2f, 0f),  //铁片2向外
          new Vector3(-3f, 0f, 0f),  //铁片3螺丝向外
          new Vector3(-3f, 0f, 0f),  //铁片3向外
          new Vector3(0f, 0f, -0.3f),  //整体下方向下
          new Vector3(3f, 0f, -0.3f) }; //整体下方向右

        moveTime = new float[] { 1f,3f,2f,2f,2f,2f,2f,2f,2f,2f,3f };
        StartCoroutine(Spilt_Merge());
    }
    IEnumerator Spilt_Merge()
    {
        //StepA.transform.DOLocalMove(targetStepA1, moveSpeed).SetEase(Ease.Linear);
        for (int i = 0; i < objects.Length; i++)
        {
            if (i > 0)
            {
                yield return objects[i - 1].transform.DOLocalMove(targetPositions[i - 1], moveTime[i - 1]).WaitForCompletion();
            }
            yield return objects[i].transform.DOLocalMove(targetPositions[i], moveTime[i]).WaitForCompletion();
        }      
    }
}

你可能感兴趣的:(unity,游戏引擎)