1、创建地形
创建地形,长宽设置55.
创建55个格子的地形
设定角色
创建一个胶囊,添加刚体组件,冻结旋转,将相机设置为胶囊的子物体(相机跟随),把胶囊标签设置为player。
创建脚本,挂载到胶囊上。
冻结旋转
代码:简单的移动(旧版输入系统)
在游戏窗口按上下左右即可。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
// 旧版输入系统
// 获取水平轴
float horizontal = Input.GetAxis("Horizontal");
// 获取垂直轴
float vertical = Input.GetAxis("Vertical");
// 获取一个玩家要移动的向量
Vector3 dir = new Vector3(horizontal, 0, vertical);
if (dir != Vector3.zero)
{
// 移动 向量方向、每秒、3个距离
transform.Translate(dir * Time.deltaTime * 3);
}
}
}
效果:
重点:无缝地图
在编辑画面中框选多余的地图设置为非激活状态。
创建脚本,声明地形的变量,将所有地形拖动上去。
选中胶囊,将检查器锁上。
注意将第一个Terrain重命名为:Terrain_(0.00, 0.00, 0.00)
脚本代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class PlayerControl : MonoBehaviour
{
// 声明放置地形的容器
public Terrain[] terrains;
void Start()
{
Debug.Log("对对对");
}
// Update is called once per frame
void Update()
{
// 旧版输入系统
// 获取水平轴
float horizontal = Input.GetAxis("Horizontal");
// 获取垂直轴
float vertical = Input.GetAxis("Vertical");
// 获取一个玩家要移动的向量
Vector3 dir = new Vector3(horizontal, 0, vertical);
if (dir != Vector3.zero)
{
// 移动 向量方向、每秒、3个距离
transform.Translate(dir * Time.deltaTime * 3);
}
}
// 获取主角的所属地形的坐标
private void OnCollisionEnter(Collision collision)
{
string name = collision.gameObject.name;
Debug.Log(name);
// 重命名 (根据创建地形的命名规则-使用的办法)
name = name.Replace("Terrain_(","").Replace(")","");
// name = name.Replace("Terrain_(","").Replace(")","");
// , 分割
string[] pos_s = name.Split(",");
// 获得x,z的偏移数值
float x = float.Parse(pos_s[0]);
float z = float.Parse(pos_s[2]);
// 计算周围地面
List<string> names = new List<string>();
for (int i=-5; i <= 5; i += 5)
{
for (int j=-5;j<=5;j+=5)
{
// 拼接周围地面的名称
string tmp = string.Format("Terrain_({0:0.00}, 0.00, {1:0.00})", x + i, z + j);
Debug.Log(tmp);
Debug.Log("--------");
names.Add(tmp);
}
}
/*
foreach (string i in names)
{
Debug.Log(i);
}
*/
// 激活周围地面
foreach(string tmp1 in names)
{
// 显示看得到的地形
SetTerrain(tmp1, true);
}
// 隐藏远处看不到的地面
foreach (Terrain terrain in terrains)
{
// 如果看不到的地面
if (!names.Contains(terrain.name))
{
// 隐藏看不到的地形
SetTerrain(terrain.name, false);
}
}
}
void SetTerrain(string name, bool active)
{
/*
// 循环遍历 terrains数组中的每个内容
foreach (Terrain terrain in terrains)
{
// 判断是否包含该名称
if (terrain.name == name)
{
// 激活 或者 取消激活
terrain.gameObject.SetActive(active);
}
}
*/
// 我非要用for循环试试看这么写好不好用
for (int i=0; i < terrains.Length; i++)
{
if (terrains[i].name == name)
{
terrains[i].gameObject.SetActive(active);
}
}
}
}