临近毕业之初,进入Unity3D这个行业,是一家小工作室,老板人很不错,公司氛围也很单纯。最近公司开发一款小游戏,初次上手,颇多周折,记录下自己的开发心得,主要涉及一些设计理念,互相交流。
先说下项目背景,主要是一款闯关游戏,山寨了敲冰块与雷霆战机。
一、人物控制
// This script moves the character controller forward
// and sideways based on the arrow keys.
//这个脚本用箭头键向前移动和侧移角色控制器。
// It also jumps when pressing space.
//当按下空格键时,它跳起。
// Make sure to attach a character controller to the same game object.
//确保把一个character controller组件附加到同一个游戏物体上。
//It is recommended that you make only one call to Move or SimpleMove per frame.
//建议你每帧只调用一次Move或者SimpleMove。
var speed : float = 6.0;
var jumpSpeed : float = 8.0;
var gravity : float = 20.0;
private var moveDirection : Vector3 = Vector3.zero;
function Update() {
var controller : CharacterController = GetComponent(CharacterController);
if (controller.isGrounded) {
// We are grounded, so recalculate
// move direction directly from axes
//我们着地了,所以直接通过轴重新计算move direction。
moveDirection = Vector3(Input.GetAxis("Horizontal"), 0,Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton ("Jump")) {
moveDirection.y = jumpSpeed;
}
}
// Apply gravity
//应用重力。
moveDirection.y -= gravity * Time.deltaTime;
// Move the controller
//移动控制器。
controller.Move(moveDirection * Time.deltaTime);
}
上面的一段代码是圣典中的一段角色控制代码。也是我项目最原始的人物控制代码版本。但是考虑到输入设备的不同,我们就要考虑到代码的重用性,比如Android移动平台和PC平台等等。
二、设计思想
可以把输入设备做一个输入模块,发出信号,其内部的逻辑实现都运动控制模块实现。这样就分离了开来,耦合性降低。
大致思想如下图所示
三、代码实现
这个设计严格说起来可能还有点复杂,但是我本身很欣赏这个做法——逻辑和表现的分离。
下面附上核心代码
类图如下
PCInput.CS
public class PCInput : MonoBehaviour {
private PlayControl mycontrol;
void Awake()
{
mycontrol = GetComponent<PlayControl>();
DebugUtils.Assert(mycontrol != null );
}
// Update is called once per frame
void Update () {
mycontrol.ChangePosition(Input.GetAxis("Horizontal"));
if (Input.GetButton("Jump"))
{
//call jump
mycontrol.Set_Jump();
}
}
}
PlayControl.CS
public void ChangePosition(float x)
{
if (isGrounded()) {
//print("isgrond");
moveDirection = new Vector3(x, 0.0f, 0.0f);
if (Startjump) {
moveDirection.y = jumpSpeed;
}
//只有在地面才能控制速度
moveDirection *= speed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
public bool Startjump = false;
void Recover()
{
Startjump = false;
}
public void Set_Jump() {
Startjump = true;
Invoke ("Recover", 0.1f);
}
Android就不发了, 本身都是一个思路。
四、延伸
其实这个模块也可以用来控制动画,比如行走和静止的动画可以由虚拟轴控制等等。
欢迎大家对博客的留言讨论。CSDN的博客发布越来越慢,还需要验证码,烦死了,后期转到博客园去了。