Unity 绘制弹球和台球的运动轨迹

效果图

废话不多说,直接上效果图

原理

原理就是创建一个 轨迹球,在第二场景中模拟白球的物理运动轨迹,并记录轨迹! 也就是创建一个不可见的场景,用来模拟球的运动轨迹绘制。

碰撞后,被碰撞物体的运动轨迹绘制 将动量传递给碰撞对象,得到碰撞的对象。 从而记录被碰撞对象的运动轨迹

场景

Physics为物理场景,GoBallList用来存放要反射的小球,TrackBallTransform为要模拟的轨迹球

代码

有两个关键的代码:

调用 physicsScene.Simulate(0.02f);完成轨迹预测;

这个API 需要 Physics.autoSimulation = false;//关闭 物理模拟 

具体代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using Lean.Touch;
using DG.Tweening;
using UnityEngine.SceneManagement;

public class BallPool : MonoBehaviour
{       
    public List<GameObject> GoBallList = new List<GameObject>();//所有的反射小球
    public Transform trackBallTransform;//轨迹球(即需要物理模拟的小球)
    private Rigidbody2D trackBallRigidbody;//轨迹球的刚体
    private PhysicsScene2D physicsScene;       //物理场景
    public Vector3 vecBallPoint;//轨迹球的位置    

    private void Start()
    {
        CreateBallReflect();//创建反射小球
        CreatePhysicsScene();//创建一个用于模拟的场景
    }

    private void OnEnable()
    {
        LeanTouch.OnFingerDown += OnFingerDown;
        LeanTouch.OnFingerSet += OnFingerSet;
        LeanTouch.OnFingerUp += OnFingerUp;
    }    

    private void OnDisable()
    {
        LeanTouch.OnFingerDown -= OnFingerDown;
        LeanTouch.OnFingerSet -= OnFingerSet;
        LeanTouch.OnFingerUp -= OnFingerUp;
    }

    //创建反射小球
    private void CreateBallReflect()
    {
        //创建轨迹球
        trackBallTransform = ObjectPool.Instance.Spawn("BallTrack", LobbyCtrl.Instance.transform.parent).transform;
        trackBallTransform.name = "TrackBall";
        trackBallTransform.position = vecBallPoint;
        trackBallRigidbody = trackBallTransform.GetComponent<Rigidbody2D>();
        UIHelper.SetActive(false, trackBallTransform);

        //创建20个白色反射小球,并隐藏
        for (int i = 0; i < 20; i++)
        {
            GameObject ball = ObjectPool.Instance.Spawn(Const.Prefab_Obj_BallReflect, transform);
            ball.name = "BallReflect";
            GoBallList.Add(ball);
        }
        for (int i = 0; i < GoBallList.Count; i++)
        {
            UIHelper.SetActive(false, GoBallList[i]);
        }
    }

    //创建一个用于模拟的场景
    private void CreatePhysicsScene()
    {
        var scene = SceneManager.CreateScene("Physics");
        physicsScene = scene.GetPhysicsScene2D();
        //将轨迹球移动到物理场景里
        SceneManager.MoveGameObjectToScene(trackBallTransform.gameObject, scene);
        
    }   

    private void MoveFinger(LeanFinger finger)
    {        
        //显示轨迹球
        UIHelper.SetActive(true, trackBallTransform);
        //关闭 物理
        Physics2D.autoSimulation = false; 
        //每次移动需要重置轨迹球的位置和力
        trackBallTransform.position = ballCtrl.transform.position;
        trackBallRigidbody.velocity = Vector3.zero;

        Vector2 screenPoint = Camera.main.ScreenToWorldPoint(finger.ScreenPosition);
        var dir = (screenPoint - (Vector2)ballCtrl.transform.position).normalized;
        //让轨迹球开始物理模拟
        trackBallRigidbody.AddForce(dir * Const.BallSpeed);

        for (int i = 0; i < GoBallList.Count; i++)
        {
            GameObject ball = GoBallList[i];
            UIHelper.SetActive(true, ball);
            physicsScene.Simulate(0.02f);//必须加这一句,值越小白色反射球间距越小
            ball.transform.position = trackBallTransform.position;//所有的白色反射小球会放置到轨迹球经过的位置上
        }
    }

    //按下
    private void OnFingerDown(LeanFinger finger)
    {                
        MoveFinger(finger);
    }

    //移动
    private void OnFingerSet(LeanFinger finger)
    {       
        MoveFinger(finger);
    }

    //松开
    private void OnFingerUp(LeanFinger finger)
    {        
        //打开物理
        Physics2D.autoSimulation = true;        
    }

    //回收弹球
    void ClearBallList()
    {        
        UIHelper.SetActive(false, trackBallTransform);
        for (int i = 0; i < GoBallList.Count; i++)
        {
            ObjectPool.Instance.Unspawn(GoBallList[i]);
        }
    }   
    
}

Unity中,可以使用LineRenderer组件来绘制运动轨迹。LineRenderer可以在Scene视图中绘制2D或3D的线条,可以用来绘制飞行路径、行动轨迹等。 首先,需要在场景中创建一个空物体并将LineRenderer组件添加到该物体上。可以通过在Inspector面板中单击“Add Component”按钮,然后搜索并选择LineRenderer来添加。 然后,在代码中,需要对LineRenderer进行初始化和设置。可以使用以下方法来设置LineRenderer的属性: 1. 使用SetPositions方法:可以通过将一个Vector3数组传递给SetPositions方法,来设置轨迹的顶点位置。例如,positions数组可以包含物体的位置在不同时间点的坐标。 2. 设置线的宽度和材质:可以使用SetWidth和SetColors方法来设置线条的宽度和颜色。 另外,通过在代码中更新LineRenderer的顶点位置,可以在运动过程中动态显示轨迹。可以使用AddPosition方法将新的位置添加到LineRenderer的顶点列表中,并使用SetPositions方法将新的顶点列表设置给LineRenderer。 最后,可以将这个空物体与运动对象进行关联,使其能够在运动过程中显示轨迹。可以在运动对象的脚本中,通过获取空物体的LineRenderer组件,并在每次更新时,将对象的位置信息传递给LineRenderer来更新轨迹。 通过以上步骤,就可以在Unity绘制运动轨迹了。可以根据需要自定义线条的宽度、颜色和材质,以及更新顶点位置的频率,来实现所需的效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值