- 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.
推薦閱讀
- SQL Server 2012數據庫技術與應用(微課版)
- Test-Driven Development with Mockito
- Learning Spring Boot
- 算法與數據中臺:基于Google、Facebook與微博實踐
- 企業級數據與AI項目成功之道
- Python金融數據分析(原書第2版)
- 信息學競賽寶典:數據結構基礎
- 智慧的云計算
- 探索新型智庫發展之路:藍迪國際智庫報告·2015(上冊)
- Spark分布式處理實戰
- 企業主數據管理實務
- Mastering ROS for Robotics Programming(Second Edition)
- 一本書讀懂大數據
- 數據中心UPS系統運維
- 數據庫技術與應用:SQL Server 2008