描述
- 注意操控行为是用算法控制游戏体从而实现自主运动的,执行过程用户不得加以干预和控制。
- 用Unity创建一个简单的游戏场景,导入游戏角色,编写游戏脚本实现其中一个操控行为案例。
实现过程
普通操作
操作
-
建立一个简单的场景。首先创建一个平面(plane),设定一个目标点(cube),添加一个简单胶囊体作为AI角色(AI)。
-
项目添加Steering脚本、Vehicle脚本。
Steering脚本
using UnityEngine;
using System.Collections;
public abstract class Steering : MonoBehaviour {
public float weight = 1;
void Start () {
}
void Update () {
}
public virtual Vector3 Force()
{
return new Vector3(0,0,0);
}
}
Vehicle脚本
using UnityEngine;
using System.Collections;
//using System.Collections.Generic;
public class Vehicle : MonoBehaviour {
private Steering[] steerings;
public float maxSpeed = 10;
public float maxForce = 100;
protected float sqrMaxSpeed;
public float mass = 1;
public Vector3 velocity;
public float damping = 0.9f;
public float computeInterval = 0.2f;
public bool isPlanar = true;
private Vector3 steeringForce;
protected Vector3 acceleration;
//private CharacterController controller;
//private Rigidbody theRigidbody;
//private Vector3 moveDistance;
private float timer;
protected void Start ()
{
steeringForce = new Vector3(0,0,0);
sqrMaxSpeed = maxSpeed * maxSpeed;
//moveDistance = new Vector3(0,0,0);
timer = 0;
steerings = GetComponents<Steering>();
//controller = GetComponent<CharacterController>();
//theRigidbody = GetComponent<Rigidbody>();
}
void Update ()
{
timer += Time.deltaTime;
steeringForce = new Vector3(0,0,0);
//ticked part, we will not compute force every frame
if (timer > computeInterval)
{
foreach (Steering s in steerings)
{
if (s.enabled)
steeringForce += s.Force()*s.weight;
}
steeringForce = Vector3.ClampMagnitude(steeringForce,maxForce);
acceleration = steeringForce / mass;
timer = 0;
}
}
/*
void FixedUpdate()
{
velocity += acceleration * Time.fixedDeltaTime;
if (velocity.sqrMagnitude > sqrMaxSpeed)
velocity = velocity.normalized * maxSpeed;
moveDistance = velocity * Time.fixedDeltaTime;
if (isPlanar)
moveDistance.y = 0;
if (controller != null)
controller.SimpleMove(velocity);
else if (theRigidbody == null || theRigidbody.isKinematic)
transform.position += moveDistance;
else
theRigidbody.MovePosition(theRigidbody.position + moveDistance);
//updata facing direction
if (velocity.sqrMagnitude > 0.00001)
{
Vector3 newForward = Vector3.Slerp(transform.forward, velocity, damping * Time.deltaTime);
newForward.y = 0;
transform.forward = newForward;
}
}*/
}
- 为AI角色添加character controller组件、AILocomotion脚本、SteeringForSeek脚本。
AILocomotion脚本
控制AI角色移动
using UnityEngine;
using System.Collections;
public class AILocomotion : Vehicle
{
private CharacterController controller;
private Rigidbody theRigidbody;
private Vector3 moveDistance;
public bool displayTrack;
// Use this for initialization
void Start ()
{
controller = GetComponent<CharacterController>();
theRigidbody = GetComponent<Rigidbody>();
moveDistance = new Vector3(0,0,0);
base.Start();
}
void FixedUpdate()
{
velocity += acceleration * Time.fixedDeltaTime;
if (velocity.sqrMagnitude > sqrMaxSpeed)
velocity = velocity.normalized * maxSpeed;
moveDistance = velocity * Time.fixedDeltaTime;
if (isPlanar)
{
velocity.y = 0;
moveDistance.y = 0;
}
if (displayTrack)
//Debug.DrawLine(transform.position, transform.position + moveDistance, Color.red,30.0f);
Debug.DrawLine(transform.position, transform.position + moveDistance, Color.black, 30.0f);
if (controller != null)
{
//if (displayTrack)
//Debug.DrawLine(transform.position, transform.position + moveDistance, Color.blue,20.0f);
controller.SimpleMove(velocity);
}
else if (theRigidbody == null || theRigidbody.isKinematic)
{
transform.position += moveDistance;
}
else
{
theRigidbody.MovePosition(theRigidbody.position + moveDistance);
}
//updata facing direction
if (velocity.sqrMagnitude > 0.00001)
{
Vector3 newForward = Vector3.Slerp(transform.forward, velocity, damping * Time.deltaTime);
if (isPlanar)
newForward.y = 0;
transform.forward = newForward;
}
//gameObject.animation.Play("walk");
}
}
SteeringForSeek脚本
public class SteeringForSeek : Steering {
public GameObject target;
private Vector3 desiredVelocity;
private Vehicle m_vehicle;
private float maxSpeed;
private bool isPlanar;
void Start () {
m_vehicle = GetComponent<Vehicle>();
maxSpeed = m_vehicle.maxSpeed;
isPlanar = m_vehicle.isPlanar;
}
public override Vector3 Force()
{
desiredVelocity = (target.transform.position - transform.position).normalized * maxSpeed;
if (isPlanar)
desiredVelocity.y = 0;
return (desiredVelocity - m_vehicle.velocity);
}
}
结果
AI角色跟随cube移动。在cube不动的情况下,AI角色围绕cube运动。
进阶操作
简要描述
- 给cube和AI角色添加刚体。
- 控制cube行动。做出类似宠物跟随系统。
过程及其结果
- 给cube和AI角色添加刚体。
- 控制cube行动。做出类似宠物跟随系统。
cube添加PlayerControl脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
private Rigidbody my_rigidbody;
private Transform my_transform;
// Use this for initialization
void Start ()
{
my_rigidbody=gameObject.GetComponent<Rigidbody> ();
my_transform=gameObject.GetComponent<Transform> ();
}
void FixedUpdate ()
{
if (Input.GetKey (KeyCode.W))
my_rigidbody.velocity = new Vector3(0, 0, 1);
if (Input.GetKey (KeyCode.S))
my_rigidbody.velocity = new Vector3(0, 0, -1);
if (Input.GetKey (KeyCode.A))
my_rigidbody.velocity = new Vector3(-1, 0, 0);
if (Input.GetKey (KeyCode.D))
my_rigidbody.velocity = new Vector3(1, 0, 0);
}
}
运行结果
cube移动的同时,AI跟随cube移动。