- Unity 5.x Game AI Programming Cookbook
- Jorge Palacios
- 328字
- 2021-07-09 19:37:48
Facing objects
Real-world aiming, just like in combat simulators, works a little differently from the widely-used automatic aiming in almost every game. Imagine that you need to implement an agent controlling a tank turret or a humanized sniper; that's when this recipe comes in handy.
Getting ready
We need to make some modifications to our AgentBehaviour
class:
- Add new member values to limit some of the existing ones:
public float maxSpeed; public float maxAccel; public float maxRotation; public float maxAngularAccel;
- Add a function called
MapToRange
. This function helps in finding the actual direction of rotation after two orientation values are subtracted:public float MapToRange (float rotation) { rotation %= 360.0f; if (Mathf.Abs(rotation) > 180.0f) { if (rotation < 0.0f) rotation += 360.0f; else rotation -= 360.0f; } return rotation; }
- Also, we need to create a basic behavior called
Align
that is the stepping stone for the facing algorithm. It uses the same principle asArrive
, but only in terms of rotation:using UnityEngine; using System.Collections; public class Align : AgentBehaviour { public float targetRadius; public float slowRadius; public float timeToTarget = 0.1f; public override Steering GetSteering() { Steering steering = new Steering(); float targetOrientation = target.GetComponent<Agent>().orientation; float rotation = targetOrientation - agent.orientation; rotation = MapToRange(rotation); float rotationSize = Mathf.Abs(rotation); if (rotationSize < targetRadius) return steering; float targetRotation; if (rotationSize > slowRadius) targetRotation = agent.maxRotation; else targetRotation = agent.maxRotation * rotationSize / slowRadius; targetRotation *= rotation / rotationSize; steering.angular = targetRotation - agent.rotation; steering.angular /= timeToTarget; float angularAccel = Mathf.Abs(steering.angular); if (angularAccel > agent.maxAngularAccel) { steering.angular /= angularAccel; steering.angular *= agent.maxAngularAccel; } return steering; } }
How to do it...
We now proceed to implement our facing algorithm that derives from Align
:
- Create the
Face
class along with a private auxiliary target member variable:using UnityEngine; using System.Collections; public class Face : Align { protected GameObject targetAux; }
- Override the
Awake
function to set up everything and swap references:public override void Awake() { base.Awake(); targetAux = target; target = new GameObject(); target.AddComponent<Agent>(); }
- Also, implement the
OnDestroy
function to handle references and avoid memory issues:void OnDestroy () { Destroy(target); }
- Finally, define the
GetSteering
function:public override Steering GetSteering() { Vector3 direction = targetAux.transform.position - transform.position; if (direction.magnitude > 0.0f) { float targetOrientation = Mathf.Atan2(direction.x, direction.z); targetOrientation *= Mathf.Rad2Deg; target.GetComponent<Agent>().orientation = targetOrientation; } return base.GetSteering(); }
How it works...
The algorithm computes the internal target orientation according to the vector between the agent and the real target. Then, it just delegates the work to its parent class.
推薦閱讀
- Redis使用手冊
- SQL Server 2016 數據庫教程(第4版)
- Greenplum:從大數據戰略到實現
- Python數據分析入門:從數據獲取到可視化
- Creating Mobile Apps with Sencha Touch 2
- 正則表達式必知必會
- 業務數據分析:五招破解業務難題
- 高維數據分析預處理技術
- Google Cloud Platform for Developers
- 從實踐中學習sqlmap數據庫注入測試
- 數據挖掘競賽實戰:方法與案例
- 數據分析思維:產品經理的成長筆記
- AndEngine for Android Game Development Cookbook
- 從Lucene到Elasticsearch:全文檢索實戰
- 數據挖掘與數據化運營實戰:思路、方法、技巧與應用