tk2d的tilemap demo的脚本研究

本文深入探讨了在游戏开发中利用脚本来实现玩家行为控制、摄像头跟随和金币互动等关键功能,包括如何通过代码实现平滑缩放效果及优化金币不在摄像头视野内的行为。详细介绍了如何通过控制物理属性、处理输入事件和调整视图来提升游戏体验,特别关注于玩家控制的响应性、视觉反馈和资源的高效利用。

 tilemap的demo脚本,大概注释一下

tk2dTileMapDemoPlayer.cs主要是控制玩家的行动和检测金币的碰撞,及时处理文字。

using UnityEngine;
using System.Collections;

public class tk2dTileMapDemoPlayer : MonoBehaviour {

	public tk2dTextMesh textMesh;//得分
	public tk2dTextMesh textMeshLabel;//score

	Vector3 textMeshOffset;//装B,不用附属关系,手动保存偏移量,用来设置坐标
	bool textInitialized = false;

	public float addForceLimit = 1.0f;
	public float amount = 500.0f;
	public float torque = 50;
	tk2dSprite sprite;
	int score = 0;
	float forceWait = 0;
	float moveX = 0.0f;
	bool AllowAddForce { get { return forceWait < 0.0f; } }

	void Awake() {
		sprite = GetComponent<tk2dSprite>();

		if (textMesh == null || textMesh.transform.parent != transform) {
			Debug.LogError("Text mesh must be assigned and parented to player.");
			enabled = false;
		}

		textMeshOffset = textMesh.transform.position - transform.position;
		textMesh.transform.parent = null;

//上面这几行就是装B,它一定要确保textmesh的父物体是玩家,然后保存textmesh和player坐标的偏移量后,把textmesh的父物体设置为空。
		
		textMeshLabel.text = "instructions";
		textMeshLabel.Commit();

		if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer ||
			Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXWebPlayer || Application.platform == RuntimePlatform.OSXDashboardPlayer) {
			textMesh.text = "LEFT ARROW / RIGHT ARROW";
		}
		else {
			textMesh.text = "TAP LEFT / RIGHT SIDE OF SCREEN";
		}
		textMesh.Commit();


//上面几行是设置提示信息
		Application.targetFrameRate = 60;
	}
	
	void Update() {
		forceWait -= Time.deltaTime;


//根据是否等待状态设置精灵的图像,绿色和红色
		string spriteName = AllowAddForce ? "player" : "player_disabled";
		if (sprite.CurrentSprite.name != spriteName) {
			sprite.SetSprite(spriteName);
		}

		if (AllowAddForce) {
			float x = 0;

			if (Input.GetKeyDown(KeyCode.RightArrow)) x = 1;
			else if (Input.GetKeyDown(KeyCode.LeftArrow)) x = -1;

			for (int i = 0; i < Input.touchCount; ++i) {
				if (Input.touches[i].phase == TouchPhase.Began) {
					x = Mathf.Sign(Input.touches[i].position.x - Screen.width * 0.5f);
					break;
				}
			}

			if (x != 0) {
				// make sure text meshes are changed on first button press / touch
//这里是按下控制键后,消去提示信息,只执行一次。


				if (!textInitialized) {
					textMeshLabel.text = "score";
					textMeshLabel.Commit();
					textMesh.text = "0";
					textMesh.Commit();
					textInitialized = true;
				}

				// The actual applying of force is deferred to the next FixedUpdate for predictable
				// physics behaviour
				moveX = x;
			}
		}

		textMesh.transform.position = transform.position + textMeshOffset;
	}



//处理Rigidbody时,需要用FixedUpdate代替Update

	void FixedUpdate () {
		if (AllowAddForce && moveX != 0) {
			forceWait = addForceLimit;
			rigidbody.AddForce(new Vector3(moveX * amount, amount, 0) * Time.deltaTime, ForceMode.Impulse);//施加力
			rigidbody.AddTorque(new Vector3(0,0,-moveX * torque) * Time.deltaTime, ForceMode.Impulse);//施加力矩,使player绕z轴旋转。
			moveX = 0;
		}
	}

	void OnTriggerEnter(Collider other) {
		Destroy( other.gameObject );

		score++;
		
		textMesh.text = score.ToString();
		textMesh.Commit();
	}
}

tk2dTileMapDemoFollowCam.cs主要是跟随玩家,并达到平滑缩放的效果

using UnityEngine;
using System.Collections;

public class tk2dTileMapDemoFollowCam : MonoBehaviour {

	tk2dCamera cam;
	public Transform target;
	public float followSpeed = 1.0f;

	public float minZoomSpeed = 20.0f;
	public float maxZoomSpeed = 40.0f;

	public float maxZoomFactor = 0.6f;

	void Awake() {
		cam = GetComponent<tk2dCamera>();
	}

	void FixedUpdate() {
		Vector3 start = transform.position;

//摄像头坐标向玩家坐标移动
		Vector3 end = Vector3.MoveTowards(start, target.position, followSpeed * Time.deltaTime);
		end.z = start.z;
		transform.position = end;
		
		if (target.rigidbody != null && cam != null) {

//根据player的速度向量,生成一个0~1之间的因子,用线性插值的方法确定缩放率,达到平滑过渡视野的效果,MoveTowards效果实际上和 Mathf.Lerp相同。
			float spd = target.rigidbody.velocity.magnitude;
			float scl = Mathf.Clamp01((spd - minZoomSpeed) / (maxZoomSpeed - minZoomSpeed));
			float targetZoomFactor = Mathf.Lerp(1, maxZoomFactor, scl);
			cam.ZoomFactor = Mathf.MoveTowards(cam.ZoomFactor, targetZoomFactor, 0.2f * Time.deltaTime);
		}
	}
}

tk2dTileMapDemoCoin.cs就是金币不在摄像头视野时不工作,提高效率。


通过这三个脚本,我大概学习了player的行为控制,之前我都是直接改transform,导致刚体之间可以穿过;摄像头平常我也只是简单的用lookat来实现跟随,当然这看情况。在rpg游戏中都是这样普通跟随,比如dnf的城镇移动和副本移动,只有在特殊的镜头才会缩放。在太空游戏中,我就觉得缩放效果会更好一点,飞船加速时预览更大的地图,游览星际。


### Unity 2D Tilemap 使用教程 #### 什么是 TilemapTilemap 是 Unity 中一种强大的工具,用于构建和管理基于瓦片的游戏地图。它允许开发者高效地设计复杂的 2D 地图,并支持多种层叠方式以及动态生成等功能[^1]。 #### 如何创建 Tilemap? 要开始使用 Tilemap,在 Unity 编辑器中可以通过以下步骤完成初始化: 1. **创建 Grid 对象** 在菜单栏选择 `GameObject -> 2D Object -> Grid` 来创建一个网格对象。这个对象作为所有 Tilemap 的容器。 2. **创建 Tilemap 对象** 接着,右键点击刚创建的 Grid 对象,选择 `2D Object -> Tilemap` 创建一个新的 Tilemap 层次结构。此时,Grid 和 Tilemap 将自动关联在一起[^3]。 #### 设置瓦片资源 为了填充 Tilemap,需要准备一些瓦片素材(Sprites)。以下是具体操作流程: 1. 导入所需的精灵图片到项目中的 Assets 文件夹下。 2. 打开 `Window -> 2D -> Sprite Editor` 并加载这些精灵文件进行编辑。 3. 利用 `Palette Window` (可通过 `Window -> 2D -> Palette` 启用),将精灵拖拽至调色板窗口形成可使用的瓦片集。 #### 绘制地图 一旦准备好瓦片集合,就可以利用 Tilemap 工具轻松绘制地图了: - 进入选项卡下的 Paint Mode 开始放置瓦片; - 改变画笔大小或者模式以适应不同需求; - 如果希望实现更复杂的效果比如规则化铺砖,则需引入 Rule Tiles[^4]。 #### 动态生成地图示例代码 下面提供了一段简单的脚本实例展示如何程序性生成随机分布的地表与背景: ```csharp using UnityEngine; using UnityEngine.Tilemaps; public class ProceduralMapGenerator : MonoBehaviour { [SerializeField] private RuleTile platformTile; [SerializeField] private RuleTile backgroundTile; [SerializeField] private Tilemap backgroundMap; [SerializeField] private Tilemap platformMap; public Vector2Int size = new Vector2Int(10, 10); public int seedPercentage = 30; void Start(){ GenerateMap(); } void GenerateMap(){ System.Random random = new System.Random(); for(int y=0;y<size.y;y++){ for(int x=0;x<size.x;x++){ bool isPlatform = random.Next(0,100)<seedPercentage?true:false; if(isPlatform){ platformMap.SetTile(new Vector3Int(x,y,0),platformTile); } else{ backgroundMap.SetTile(new Vector3Int(x,y,0),backgroundTile); } } } } } ``` 该脚本定义了一个矩形区域内的每格都有一定几率成为平台或其他类型的地面单元[^4]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值