角色控制器是unity内置的一个人物控制脚本。适用于第一、第三人称中控制人物的一个组件,刚体的计算量比较大, 所以出现了CharacterController来代替刚体,做具体的人物控制。

 

常用属性介绍

Unity角色控制器CharaterController脚本之美_Unity教程

Slop Limit : 坡度的限制,限制角色可以爬坡的最大角度

Step Offset : 高度限制,上楼梯时一步的最大高度

Skin Width : 皮肤厚度

Min Move Distance : 最小移动距离

Center : 角色控制中心

Radius : 角色控制器的半径

Height : 角色控制器的高度

这些值一般由策划设置

例子一

pc电脑上通过点击来使人物移动

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// People test.
/// 使用角色控制器,控制角色移动(播放动画)
/// eg:移动到鼠标点击的位置(地面上走)
/// </summary>
public class PeopleTest : MonoBehaviour
{
    Animation _ani;
    CharacterController _characterCtrl;
    //人物移动的目的地
    Vector3 _v = Vector3.zero;
    void Awake()
    {
        _ani = GetComponent<Animation>();
        _characterCtrl = GetComponent<CharacterController>();
    }
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            //射线:从相机位置向鼠标点击位置法射射线
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            //射线碰撞的信息
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                //检测射线是否发生碰撞,(碰到地面、人、墙)
                _v = hit.point; //碰撞的这个点
            }
        }
        if (Vector3.Distance(_v, transform.position) > 0.5f)
        {
            Debug.Log("Run");
            transform.LookAt(_v);
            _ani.Play("Run");
            _characterCtrl.SimpleMove(transform.forward * 5);
        }
        else
        {
            _ani.Play("Idle");
        }
    }
}

会出现的bug:

1. 人物角色控制器脚本里的碰撞器和地面的碰撞器不要重合,叠在一起,否则会出现一直往某地转圈的情况

2. 如果点自己会出现bug,因为射线没有做具体判断,可以加上一个if条件判断一下

 

例图

Unity角色控制器CharaterController脚本之美_Unity教程_02

例子二

 

在手游上,通过摇杆(Axis判断)控制人物移动

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// People test.
/// 使用角色控制器,控制角色移动(播放动画)
/// eg:wasd移动,用轴线Axis的值计算(地面上走)
/// </summary>
public class PeopleTest : MonoBehaviour
{
    Animation _ani;
    CharacterController _characterCtrl;
    //人物移动的目的地
    Vector3 _v = Vector3.zero;
    void Awake()
    {
        _ani = GetComponent<Animation>();
        _characterCtrl = GetComponent<CharacterController>();
    }
    void Update()
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
        if (x != 0 || z != 0)
        {
            _v.x = transform.position.x + x;
            _v.z = transform.position.z + z;
            _v.y = transform.position.y;
            transform.LookAt(_v);
            _ani.Play("Run");
            _characterCtrl.SimpleMove(transform.forward * 2);
        }
        else
        {
            _ani.Play("Idle");
        }
    }
}

注意

SimpleMove() : 会受到重力的影响

Move() : 不会受到重力的影响 (不常用)

区别 : 当时有SimpleMove()人物不会默认滑动

使用Move()人物会默认滑动(位置改变)