zoukankan      html  css  js  c++  java
  • [Unity算法]斜抛运动(变种)

    之前的斜抛运动,如果运动到游戏中,显然是太呆板了,那么可以试着加入一些效果,让它看起来更生动一些,类似游戏中的击飞或者掉落效果:

    1.在达到最高点的时间点±X的时间段内,会有“减速”效果,形成一种在空中停留的感觉

    2.落地后,反弹一次,再落地,就像是与地面发生了碰撞

    相关公式:

    ObliqueThrow.cs

      1 using System;
      2 using UnityEngine;
      3 
      4 public class ObliqueThrow : MonoBehaviour {
      5 
      6     private float gravity;                      //重力加速度(当前)
      7     private float gravityValue = -9.8f;         //重力加速度值1
      8     private Vector2 horizontalDir;              //水平方向
      9     private float startSpeed;                   //初速度
     10     private float sinValue;                     //sin值
     11     private float cosValue;                     //cos值
     12     private Vector3 startPos;                   //开始位置
     13     private float endY;                         //结束高度(地面高度)
     14     private float timer;                        //运动消耗时间
     15     private Action<GameObject> finishCallBack;  //落地后的回调
     16     private bool canMove = false;               //能否运动
     17 
     18     private float timeScale = 1;                //时间系数
     19     private float reboundTimes = 1;             //反弹次数
     20     private bool isInRebound = false;           //是否在反弹中
     21     private float lastX;                        //落地点x
     22     private float lastZ;                        //落地点z
     23     private float hightestPointTime;            //到达最高点所用的时间
     24     private float hightestPointStayTime = 0.1f; //最高点减速范围的时间段
     25 
     26     void Update()
     27     {
     28         if (!canMove)
     29         {
     30             return;
     31         }
     32 
     33         //移动过程
     34         timer = timer + Time.deltaTime * timeScale;
     35 
     36         float xOffset = startSpeed * timer * cosValue * horizontalDir.x;
     37         float zOffset = startSpeed * timer * cosValue * horizontalDir.y;
     38         float yOffset = startSpeed * timer * sinValue + 0.5f * gravity * timer * timer;
     39 
     40         Vector3 endPos;
     41         if (!isInRebound) //非反弹过程
     42         {
     43             endPos = startPos + new Vector3(xOffset, yOffset, zOffset);
     44             if (Mathf.Abs(timer - hightestPointTime) < hightestPointStayTime)
     45             {
     46                 timeScale = 0.5f;
     47             }
     48             else
     49             {
     50                 timeScale = 1f;
     51             }
     52         }
     53         else //反弹过程
     54         {
     55             endPos = new Vector3(lastX, yOffset, lastZ);
     56         }
     57 
     58         //落地
     59         if (endPos.y < endY)
     60         {
     61             endPos.y = endY;
     62 
     63             reboundTimes = reboundTimes - 1;
     64             if (reboundTimes < 0) //移动结束
     65             {
     66                 canMove = false;
     67             }
     68             else //落地反弹
     69             {
     70                 gravity = gravityValue * 2;
     71                 horizontalDir = Vector2.zero;
     72                 startSpeed = startSpeed * 0.8f;
     73                 sinValue = 1;
     74                 cosValue = 0;
     75                 timer = 0;
     76 
     77                 isInRebound = true;
     78                 lastX = endPos.x;
     79                 lastZ = endPos.z;
     80             }
     81         }
     82         transform.position = endPos;
     83 
     84         //移动结束
     85         if (!canMove)
     86         {
     87             finishCallBack(gameObject);
     88             Destroy(this);
     89         }
     90     }
     91 
     92     public void StartMove(Vector2 horizontalDir, float startSpeed, float angle, float endY, Action<GameObject> finishCallBack)
     93     {
     94         gravity = gravityValue;
     95         this.horizontalDir = horizontalDir;
     96         this.startSpeed = startSpeed;
     97         sinValue = Mathf.Sin(Mathf.Deg2Rad * angle);
     98         cosValue = Mathf.Cos(Mathf.Deg2Rad * angle);
     99         startPos = transform.position;
    100         this.endY = endY;
    101         timer = 0;
    102         this.finishCallBack = finishCallBack;
    103         canMove = true;
    104 
    105         hightestPointTime = Mathf.Abs(startSpeed * sinValue / gravity);
    106     }
    107 }

    TestThrow.cs

     1 using UnityEngine;
     2 using System.Collections.Generic;
     3 
     4 public class TestThrow : MonoBehaviour {
     5 
     6     public GameObject testGo;
     7     private bool isDebug = false; 
     8     private List<GameObject> drawGoList = new List<GameObject>();
     9 
    10     void Update ()
    11     {
    12         if (Input.GetKeyDown(KeyCode.Q))
    13         {
    14             //半径为1的方向圆
    15             float randomNum = Random.Range(0f, 1f);//[0, 1]
    16             float x = randomNum * 2 - 1;//[-1, 1]
    17             float z = Mathf.Sqrt(1 - x * x);
    18             if (Random.Range(0f, 1f) > 0.5f)
    19             {
    20                 z = -z;
    21             }
    22 
    23             isDebug = true;
    24             ObliqueThrow obliqueThrow = testGo.AddComponent<ObliqueThrow>();
    25             obliqueThrow.StartMove(new Vector2(1, 0), 5f, 45f, 0f, (go) => {
    26                 isDebug = false;
    27                 Debug.Log("移动结束");
    28             });
    29         }
    30         else if(Input.GetKeyDown(KeyCode.W))
    31         {
    32             testGo.transform.position = new Vector3(0f, 5f, 0f);
    33             for (int i = 0; i < drawGoList.Count; i++)
    34             {
    35                 Destroy(drawGoList[i]);
    36             }
    37             drawGoList.Clear();
    38         }
    39 
    40         if (isDebug)
    41         {
    42             GameObject go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    43             go.transform.position = testGo.transform.position;
    44             go.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
    45             drawGoList.Add(go);
    46         }
    47     }
    48 }

    效果如下:

  • 相关阅读:
    Java Lock Example – ReentrantLock(java锁的例子)
    Java Scheduler ScheduledExecutorService ScheduledThreadPoolExecutor Example(ScheduledThreadPoolExecutor例子——了解如何创建一个周期任务)
    ThreadPoolExecutor – Java Thread Pool Example(java线程池创建和使用)
    Java Timer TimerTask Example(java Timer的例子)
    Java ThreadLocal Example(java中的ThreadLocal例子)
    Thread Safety in Java(java中的线程安全)
    java 线程方法join的简单总结
    JAVA多线程和并发基础
    BAT面试常的问题和最佳答案
    linux服务脚本编写
  • 原文地址:https://www.cnblogs.com/lyh916/p/10415954.html
Copyright © 2011-2022 走看看