制作一个类似饥荒风格的2.5d游戏模板。
2.5D游戏是指以2D平面游戏为基础,加入3D元素(如3D建模、3D特效等),以营造出更加立体、丰富的游戏画面和游戏体验。与传统的2D游戏相比,2.5D游戏的画面更具质感、视觉效果更加生动,但游戏玩法和操作方式仍保持2D游戏的简单性和直观性。常见的2.5D游戏有《鬼泣》、《奥日与黑暗森林》、《超级马里奥3D世界》等。
添加树木、石头
添加碰撞器
新建一个2dsprite精灵,添加tag“player”
添加刚体,不受重力,冻结z轴旋转
添加碰撞器
添加动画器
新建动画、制作左右移动动画、前后奔跑动画
打开动画器
添加 blendtree,实现前后左右的移动
idle代表玩家不运动时候的动画,设置切换条件
添加刚体组件。
Horizontal获取水平位移,Vertical获取垂直唯一,向量标准化防止斜着运动速度太快,不正常。
使用局部坐标系移动,而不是世界坐标系。
给刚体一个瞬时速度,如果不运动了速度立刻降为0
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed;
new private Rigidbody2D rigidbody;
private Animator animator;
private float inputX, inputY;
private float stopX, stopY;
void Start()
{
rigidbody = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
void Update()
{
inputX = Input.GetAxisRaw("Horizontal");
inputY = Input.GetAxisRaw("Vertical");
Vector2 input = (transform.right * inputX + transform.up * inputY).normalized;
rigidbody.velocity = input * speed;
if (input != Vector2.zero)
{
animator.SetBool("isMoving", true);
stopX = inputX;
stopY = inputY;
}
else
{
animator.SetBool("isMoving", false);
}
animator.SetFloat("InputX", stopX);
animator.SetFloat("InputY", stopY);
}
}
点击“2d”,俯视地图,相机x轴设置45度
制作2d向2.5d转换的脚本。
把所有立体显示的物体(包括玩家),对象放在一个层次中,
脚本新建一个数组,获取当前组合中的所有子物体,和相机保持一致的旋转角度
Transform[] childs;
void Start()
{
childs = new Transform[transform.childCount];
for (int i = 0; i < transform.childCount; i++)
{
childs[i] = transform.GetChild(i);
}
}
void Update()
{
for (int i = 0; i < childs.Length; i++)
{
childs[i].rotation = Camera.main.transform.rotation;
}
}
相机要和player保持固定距离,并跟随玩家移动。
新建一个空物体,把主相机挂载到上面。
该物体一直跟随玩家移动
transform.position = player.position;
旋转视角,按下q逆时针旋转45度,按下e顺时针旋转45度。
使用协程,转化视角中可以移动
使用fixedupdate()旋转更平滑
public float rotateTime = 0.2f;
private Transform player;
private bool isRotating = false;
void Start()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update()
{
transform.position = player.position;
Rotate();
}
void Rotate()
{
if (Input.GetKeyDown(KeyCode.Q) && !isRotating)
{
StartCoroutine(RotateAround(-45, rotateTime));
}
if (Input.GetKeyDown(KeyCode.E) && !isRotating)
{
StartCoroutine(RotateAround(45, rotateTime));
}
}
IEnumerator RotateAround(float angel, float time)
{
float number = 60 * time;
float nextAngel = angel / number;
isRotating = true;
for (int i = 0; i < number; i++)
{
transform.Rotate(new Vector3(0, 0, nextAngel));
yield return new WaitForFixedUpdate();
}
isRotating = false;
}
https://wwez.lanzoul.com/i8tG30sqc8vg