在上一节中我们提到,小鸟的刚体属性发挥作用,使得小鸟刚体没有速度时才会生成第二只小鸟。
如果没有什么初始推动力变化,小鸟将以固定的模式发射,就像帝国时代中的投石车。但是,此时,小鸟还不具备主动发现目标精准打击的功能。如果小鸟能够做到自动判断,则小鸟需要对目标区域首先完成扫描才行,然后根据不同距离计算出发射初始的推动力的大小,然后实现精准打击。
小鸟需要具有几个属性,逐一进行分析,
1.刚体属性,使得小鸟能够应用重力作用实现抛物线运动。
2.小鸟在发射时应具有一定的初速度,这需要用到物理学和数学方程式。
3.小鸟精准定位目标,我们指定一个目标对象,使小鸟找到该目标对象,计算小鸟和目标对象的距离,反算抛物线轨迹。
4.小鸟轨迹必须设定抛物线轨迹吗?是否可以是直线运动。当然,为何?直线是在没有障碍物的情况下直线发射,抛物线是可以躲避障碍物的,所以我们先做个抛物线轨迹的探索吧。
5.小鸟初速度是根据系统给定的,和现实中的有一些区别。现实中如果要产生初速度,则需要物体产生能量,并且将能量转化为动能。例如喷气式飞机。
6.我们还按二维平面上进行试验。后续可以推广至三维空间中。
7.当目标物体移动变化时,小鸟能实时判断目标物体最新状态。
8.如果目标物体为多个,则小鸟需要识别到多个,如果给小鸟赋予弹药性质,可以使目标物被摧毁。这里面有两种情况,第一种是小鸟自身具有爆炸属性,遇到物体就会使物体炸裂。第二种是小鸟具有冲撞属性,当冲击力足够大时,使得物体炸裂。
好,我们试着实现这样的假设,还是按给弹弓发射小鸟的模式进行,让弹弓产生小鸟,并且小鸟具备自动定位的属性。弹弓产生小鸟的代码参考之前写的不变化。我们让小鸟具备自动定位,产生内力发射的能力。
建立脚本AutoGisThrow.cs
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
public class AutoGisThrow : MonoBehaviour
{
public Transform pointbird;//小鸟的初始位置
public Transform target;//目标物
public float heightMoreTarget;//相当于抛物线最高点到目标物体或者小鸟两者之中垂直高度较高的那个对象的垂直距离
// Start is called before the first frame update
void Start()
{
AutoThrow();
}
void AutoThrow()
{
target = GameObject.Find("wood_big").transform;
float Gravity=10f;
float heightLeft,heightRight;
Debug.Log("target.position.y is :" +target.position.y);
Debug.Log("pointbird.position.y is :" +pointbird.position.y);
float GravityTest=Mathf.Abs(Physics2D.gravity.y * pointbird.GetComponent<Rigidbody2D>().gravityScale) ;
Debug.Log("Physics2D.gravity.y is :" + Physics2D.gravity.y);
Debug.Log("Physics2D.gravity is :" + Physics2D.gravity);
Debug.Log("pointbird.GetComponent<Rigidbody2D>().gravityScale is :" + pointbird.GetComponent<Rigidbody2D>().gravityScale);
Debug.Log("GravityTest is :" + GravityTest);
Gravity = GravityTest;
if (target.position.y>pointbird.position.y)
{
heightLeft=heightMoreTarget+target.position.y-pointbird.position.y;
heightRight=heightMoreTarget;
Debug.Log("target higher ");
}
else
{
heightLeft=heightMoreTarget;
heightRight=heightMoreTarget+pointbird.position.y-target.position.y;
Debug.Log("bird higher ");
}
Debug.Log("heightLeft is :" +heightLeft);
Debug.Log("heightRight is :" +heightRight);
float timeLeft =Mathf.Sqrt(2*heightLeft/Gravity);
float timeRight=Mathf.Sqrt(2*heightRight/Gravity);
float timeAll=timeLeft+timeRight;
Debug.Log("timeLeft is :" +timeLeft);
Debug.Log("timeRight is :" +timeRight);
Debug.Log("timeAll is :" +timeAll);
Vector2 distance=target.position-pointbird.position;
Debug.Log("target.position.x is :" +target.position.x);
Debug.Log("pointbird.position.x is :" +pointbird.position.x);
Debug.Log("distance is :" +distance);
distance.y=0;
Vector2 speed=distance/timeAll;
Debug.Log("speed is :" +speed);
Vector2 velocity=speed+timeLeft*Gravity*Vector2.up;
Debug.Log("velocity is :" +velocity);
pointbird.GetComponent<Rigidbody2D>().isKinematic=false;
pointbird.GetComponent<Rigidbody2D>().AddForce(velocity,ForceMode2D.Impulse);
Debug.Log("pointbird.GetComponent<Rigidbody2D>().velocity is :" +pointbird.GetComponent<Rigidbody2D>().velocity );
}
// Update is called once per frame
void Update()
{
}
}
做一下解释:小鸟的初始位置可以通过预制体进行设定。然后通过公共参数传给pointbird。
public Transform pointbird;//小鸟的初始位置
public Transform target;//目标物
小鸟和目标物体的距离,我们通过抛物线的轨迹做出测算。本次就不采用直线的方式实现发射了。抛物线有两种情况一种是目标物高于小鸟的位置,另外一种是目标物低于小鸟的位置。这个大家可以从草稿纸上画一下模拟一下。
下面这种是弹弓低于目标物蓝色冰块。此时条件是
if (target.position.y>pointbird.position.y)
下面这种是弹弓高于目标物蓝色冰块。此时条件是
if (target.position.y<pointbird.position.y),在程序中我们用else代替。
目标物的寻找通过
target = GameObject.Find(“wood_big”).transform;
进行处理,当然我们在这段脚本中让小鸟寻找木桩。
小鸟到达目标物的轨迹,我们分为上升阶段和下降阶段。即 float heightLeft,heightRight;左面代表上升,右面代表下降。
由于小鸟能以多种抛物轨迹到达目标物,所以我们选定其中的一条轨迹,所以我们就预先定义好一个轨迹,这个轨迹是通过设定最高点和目标物之间的高度来定的。假定小鸟位置、最高点位置,heightMoreTarget代表最高点较小鸟或者目标物两者之中较高的物体的那个高度差、目标物位置全部定好。那么抛物线轨迹就是定的。
大家画个图就能看明白
通过简单的数学加减能够有以下关系。
if (target.position.y>pointbird.position.y)
{
heightLeft=heightMoreTarget+target.position.y-pointbird.position.y;
heightRight=heightMoreTarget;
Debug.Log("target higher ");
}
else
{
heightLeft=heightMoreTarget;
heightRight=heightMoreTarget+pointbird.position.y-target.position.y;
Debug.Log("bird higher ");
}
有了抛物轨迹,我们通过物理公式小鸟和目标物的横向距离计算小鸟的水平初速度和上升初速度,然后通过赋予这一初速度矢量,实现小鸟的发射并定位。
小鸟已发射。
小鸟精准打击木块。
9.当然我们本次先试验能够基准打击即可,至于爆炸属性则是需要一些爆炸的物理方面的知识,在何种物理情况下的爆炸会使得什么样的物理对象发生炸裂,如果要做到客观,则需要精心设计这个环节。如果按冲撞力算,则是另外一种情形,也需要一些物理现象的支撑。所以物理现象的模拟和游戏还是具有一些区别的,游戏是可以赋予对象一些属性的,而物理现象则是需要更加的客观一些。所以游戏能够打装备按照作者设定好的场面进行升级,而物理现象如果要模拟的真实,或者说想使得物体具有更加高级的特性,则需要有所突破的。
10.还有其他要补充的吗?大家可以留言。
11.这里想到一个情况,就是我们组建的场景中的物体目前都是设定好的属性,即使在二维场景中,物体不具备自身学习能力。物体可以被我们控制来回移动,也可以靠着我们设定的属性进行移动,但物体对周围其他物体和环境没什么反应,也没有什么认知。所谓的生命在这个平面中没有看到。假如给定了一些小动物或者叫小精灵的东西,其实也是我们设定好的一些属性,它的智能程度基本没有。
12.这就是我们所说到的第三方非控制角色了,非控制角色其实也是设定好的一些角色的属性,但是智能有没有需要打一个问号,至少简单的游戏里面是没什么智能的,就是一些属性。比如像打怪的过程,其实是设定了怪物和你是敌对的双方,只要你们是敌对属性,双方就得互相pk。
13.可以考虑怎么样使物体具有智能属性。