- 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.
推薦閱讀
- 數據庫原理及應用教程(第4版)(微課版)
- Spark快速大數據分析(第2版)
- Python金融大數據分析(第2版)
- 分布式數據庫系統:大數據時代新型數據庫技術(第3版)
- 數據庫開發實踐案例
- 大數據治理與安全:從理論到開源實踐
- R語言數據挖掘
- Unreal Engine Virtual Reality Quick Start Guide
- The Natural Language Processing Workshop
- Microsoft Dynamics NAV 2015 Professional Reporting
- Mastering Java for Data Science
- Access 2013 數據庫管理與應用從新手到高手
- Nagios Core Administrators Cookbook
- 商業銀行數據庫管理實踐
- 工業大數據工程:系統、方法與實踐