效果
无限向上延伸的墙壁.gif思路
将墙的位置设置到屏幕的左下角和右下角。
关注目标角色的PosY的变化,当达到合适的值(如当前墙高的一半时)时,修改墙的高度:
- 外观图(Sprite Renderer)的Height变化(Tiled模式)
- BoxCollider的OffsetY、SizeY的变化。
实现
-
墙壁图的参数设置
image.png -
配置墙壁
左墙
右墙 -
Wall的高度随目标角色的位置Y的变化而变化(代码控制)
Walls.cs -
相机跟随(代码控制)
Cam.cs
代码
Walls.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 可无限向上延伸的墙壁
/// </summary>
public class Walls : MonoBehaviour
{
[SerializeField]
private Transform _refTrans;
[SerializeField, Header("当refTrans的PosY达到高度的多少时,修改高度")]
private float _changeHeightRatio = 0.5f;
[SerializeField]
private float _initHeight = 50;
[SerializeField]
private float _checkHeightInterval = 1f;
[SerializeField]
private Wall _leftWall;
[SerializeField]
private Wall _rightWall;
private float CurHeight{ get; set; }
private IEnumerator Start()
{
// 设置左右墙的位置:左下角、右下角
var screenMinPos = Vector3.zero;
var screenMaxPos = new Vector3(Screen.width, Screen.height, 0);
var minPos = Camera.main.ScreenToWorldPoint(screenMinPos);
var maxPos = Camera.main.ScreenToWorldPoint(screenMaxPos);
_leftWall.SetPos(new Vector3(minPos.x, minPos.y, 0));
_rightWall.SetPos(new Vector3(maxPos.x, minPos.y, 0));
// 初始化高度
SetHeight(_initHeight);
// 每过一段时间检测一下,尝试修改高度
while (true)
{
yield return new WaitForSeconds(_checkHeightInterval);
if (_refTrans.position.y >= CurHeight * _changeHeightRatio)
{
SetHeight(CurHeight * 2);
}
}
}
private void SetHeight(float height)
{
_leftWall.SetHeight(height);
_rightWall.SetHeight(height);
CurHeight = height;
}
[System.Serializable]
private class Wall
{
[SerializeField]
private Transform _trans;
[SerializeField]
private SpriteRenderer[] _renderers;
[SerializeField]
private BoxCollider2D _col;
public void SetPos(Vector3 pos)
{
_trans.position = pos;
}
public void SetHeight(float height)
{
if (_renderers != null && _renderers.Length > 0)
{
for (int i = 0; i < _renderers.Length; i++)
{
_renderers[i].size = new Vector2(_renderers[i].size.x, height);
}
}
if (_col != null)
{
_col.size = new Vector2(_col.size.x, height);
_col.offset = new Vector2(_col.offset.x, height / 2);
}
}
}
}
Cam.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cam : MonoBehaviour
{
[SerializeField]
private Transform _camTrans;
[SerializeField]
private Transform _target;
[SerializeField]
private float _posYOffset = 0f;
[SerializeField]
private float _moveSpeed = 5f;
[SerializeField]
private float _minPosY = 15;
private void FixedUpdate()
{
_camTrans.transform.position = new Vector3(_camTrans.position.x, PosY, _camTrans.position.z);
}
private float PosY
{
get
{
return Mathf.Max(_minPosY, Mathf.Lerp(_camTrans.position.y, _target.position.y + _posYOffset, _moveSpeed * Time.fixedDeltaTime));
}
}
}
网友评论