zoukankan      html  css  js  c++  java
  • 通过射线与物体的交互

    1.鼠标平面拖拽物体

    Plane movePlane;
    float fixedDistance=2f;
    float hitDist, t;
    Ray camRay;
    Vector3 startPos, point, corPoint;
    
    void OnMouseDown (){
        startPos = transform.position; // save position in case draged to invalid place
        movePlane = new Plane(-Camera.main.transform.forward,transform.position); // find a parallel plane to the camera based on obj start pos;
    }
    
    void OnMouseDrag (){
        camRay = Camera.main.ScreenPointToRay(Input.mousePosition); // shoot a ray at the obj from mouse screen point
    
        if (movePlane.Raycast(camRay,out hitDist)){ // finde the collision on movePlane
            point = camRay.GetPoint(hitDist); // define the point on movePlane
            t=-(fixedDistance-camRay.origin.y)/(camRay.origin.y-point.y); // the x,y or z plane you want to be fixed to
            corPoint.x=camRay.origin.x+(point.x-camRay.origin.x)*t; // calculate the new point t futher along the ray
            corPoint.y=camRay.origin.y+(point.y-camRay.origin.y)*t;
            corPoint.z=camRay.origin.z+(point.z-camRay.origin.z)*t;
            transform.position = corPoint; 
        }
    }

    2.当射线碰撞目标为boot类型的物品 ,执行拾取操作(仅作参考)

        // Update is called once per frame
        void Update () 
        {
            if(Input.GetMouseButton(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从摄像机发出到点击坐标的射线
                RaycastHit hitInfo;
                if(Physics.Raycast(ray,out hitInfo))
                {
                    Debug.DrawLine(ray.origin,hitInfo.point);//划出射线,只有在scene视图中才能看到
                    GameObject gameObj = hitInfo.collider.gameObject;
                    Debug.Log("click object name is " + gameObj.name);
                    if(gameObj.tag == "boot")//当射线碰撞目标为boot类型的物品 ,执行拾取操作
                    {
                        Debug.Log("pick up!");
                    }
                }
            }
        }

    3.重置物体位移方法,脱卡需要放到摄像机下

        public static void ResetPosition(GameObject ModelSelf, GameObject target, Vector3 parentOffset)
        {
            if (target == Camera.main.gameObject)
            {
                ModelSelf.transform.parent = target.transform;
                ModelSelf.transform.localPosition = Vector3.zero + parentOffset;
                ModelSelf.transform.localRotation = Quaternion.identity;
            }
            else
            {
                ModelSelf.transform.parent = target.transform;
                ModelSelf.transform.localPosition = Vector3.zero;
                ModelSelf.transform.localRotation = Quaternion.identity;
            }
        }

    4实例,小球找同颜色父物体

      

    完整代码

    using System.Collections;
    using UnityEngine;
    
    public class DragMeOnPlane : MonoBehaviour
    {
        Plane movePlane;
        float fixedDistance = 1f; //y aixs offset
        float hitDist, t;
        Ray cameraRay;
        Vector3 startPos, point, corPoint;
        public float xLimit = 3f;  //默认限制区域为3*3平面
        public float zLimit = 3f;
    
        public Transform initPosition;      //初始位置
        public Transform targetPosition;    //目标位置
    
        bool isFindParent = false;
    
        void OnMouseDown()
        {
            startPos = transform.position; // save position in case draged to invalid place
            movePlane = new Plane(-Camera.main.transform.forward, transform.position); // find a parallel plane to the camera based on obj start pos;
        }
    
        void OnMouseDrag()
        {
            cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition); // shoot a ray at the obj from mouse screen point
    
            if (movePlane.Raycast(cameraRay, out hitDist))
            {
                if (!isFindParent)
                {
                    // finde the collision on movePlane
                    point = cameraRay.GetPoint(hitDist); // define the point on movePlane
                    t = -(fixedDistance - cameraRay.origin.y) / (cameraRay.origin.y - point.y); // the x,y or z plane you want to be fixed to
    
                    var tempX = cameraRay.origin.x + (point.x - cameraRay.origin.x) * t;   // calculate the new point t futher along the ray
                    var tempZ = cameraRay.origin.z + (point.z - cameraRay.origin.z) * t;
                    corPoint.x = Mathf.Clamp(tempX, -xLimit, xLimit);
                    corPoint.z = Mathf.Clamp(tempZ, -zLimit, zLimit);
                    corPoint.y = cameraRay.origin.y + (point.y - cameraRay.origin.y) * t;
    
                    transform.position = corPoint; 
                }
                else
                {
                    transform.localPosition = Vector3.zero;
                }
            }
        }
    
        void OnTriggerEnter(Collider game)//测试是否触发触发器
        {
            print("Enter " + game.name);
    
            if(game.name.Equals(targetPosition.name))
            {
                isFindParent = true;
                Utility.ResetPosition(gameObject, targetPosition.gameObject, Vector3.zero);
            }
            else
            {
                isFindParent = true;
                Utility.ResetPosition(gameObject, initPosition.gameObject, Vector3.zero);
                StartCoroutine(ResetIsFindParent());
            }
        }
    
        IEnumerator ResetIsFindParent()
        {
            yield return new WaitForSeconds(1f);
            isFindParent = false;
        }
    }

     5物体碰撞知识参考 http://m.manew.com/thread-30342-1-1.html

  • 相关阅读:
    那是什么进程 —— svchost.exe是什么? 它为何运行?
    共享一下我的博客皮肤
    C#3.0亮点 —— 关键字var和匿名类型
    改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)
    C#3.0亮点 —— 分部方法
    解决C#中一个"异步方法却同步执行"的问题
    改善代码设计 —— 简化函数调用(Making Method Calls Simpler)
    改善代码设计 —— 总结篇(Summary)
    理解A*寻路算法具体过程
    改善代码设计 —— 组织好你的数据(Composing Data)
  • 原文地址:https://www.cnblogs.com/JimmyCode/p/7428689.html
Copyright © 2011-2022 走看看