提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本文由小白所发,内容不好请见谅
小地图跳转
提示:以下是本篇文章正文内容,下面案例可供参考
一、小地图跳转所需要具备的组件
1.拥有一个摄像头
2.制作一张小地图
3.准备一个可实例化的物体(这里为点击生成一个标记在小地图上,当然你不需要也是可以的)
二、实现功能
1.摄像头
这里准备了一个可移动摄像头,只需要在放置在摄像头上即可。
代码如下(示例):
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour
{
// Start is called before the first frame update
public float minimumY = -90f, maximumY = 90f;
private float rotationY =0, rotationX = 0f;
public float sensitivity = 10f;
public float moveSpeed = 5f;
private float vInput,hInput;
private Vector3 origineulerAngle;
private void Start()
{
origineulerAngle = transform.localEulerAngles;
rotationY = -origineulerAngle.x;
rotationX = origineulerAngle.y;
}
void Update()
{
if (Input.GetMouseButton(1))
{
rotationX += Input.GetAxis("Mouse X") * sensitivity;
rotationY += Input.GetAxis("Mouse Y") * sensitivity;
rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);
transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
}
vInput = Input.GetAxis("Vertical") * moveSpeed;
hInput = Input.GetAxis("Horizontal") * moveSpeed;
transform.Translate(Vector3.forward * vInput * Time.deltaTime);
transform.Translate(Vector3.right * hInput * Time.deltaTime);
}
}
2.准备小地图身上的脚本
我先讲解一下具体思路:要通过点击小地图从而实现摄像头跳转,我们需要获取点击到小地图的位置投射到场景里面然后通过赋予给摄像头从而实现跳转,那么我们需要计算小地图大小从而换算到场景里面,就是Unity中的屏幕坐标转换为世界坐标。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class MiniMap : MonoBehaviour,IPointerDownHandler
{
public int maxNum;//最大实例化跳转点,可自由设置能标记几个点位
private int currentnailNUm;//记录当前的点位数量
public GameObject nail;//点位
public GameObject Camera;//摄像机
private List<GameObject> nails = new List<GameObject>();//将生成的点做成列表记录
private Vector2 minimapSize;//小地图长和宽
private Vector2 LDPosition;//小地图坐标
public Vector2 FactoryLDPos;//世界场景中的左下角坐标
public Vector2 FactorySize;//世界场景中的长宽
在开始前我们需要获取到小地图的长宽,从而通过小地图坐标来计算小地图左下角的位置,再除于长宽得到百分比,通过百分比可以换算到世界坐标的位置,因为坐标是小地图中间的位置,所以要获取到左下角位置需要通过除于长宽的各一半也就是2f就可以得到了。
private void Start()
{
minimapSize = new Vector2(GetComponent<RectTransform>().rect.width, GetComponent<RectTransform>().rect.height);//得到小地图的长宽
LDPosition = (Vector2)transform.position - minimapSize/2f;//得到左下角坐标
}
接下来就是如何将获取的坐标与将坐标赋予到世界坐标
public Vector3 ChangeMinimapPosToWorld( Vector2 ratio,float cameraY )
{
Vector3 WorldPos = new Vector2();
WorldPos.y = cameraY;
WorldPos.x = FactoryLDPos.x + FactorySize.x * ratio.x;
WorldPos.z = FactoryLDPos.y + FactorySize.y * ratio.y;
return WorldPos;
}
public void OnPointerDown(PointerEventData eventData)
{
if (currentnailNUm >= maxNum)
{
return;
}
GameObject temp = Instantiate(nail, eventData.position, Quaternion.identity);
temp.transform.SetParent(transform);
temp.GetComponent<Button>().onClick.AddListener(() =>
{
Vector2 miniMapPos = (Vector2)temp.transform.position - LDPosition;
Vector2 minMapRatio = new Vector2(miniMapPos.x / minimapSize.x, miniMapPos.y / minimapSize.y);
Camera.transform.position = ChangeMinimapPosToWorld(minMapRatio, Camera.transform.position.y);
});
nails.Add(temp);
currentnailNUm++;
Debug.Log(eventData.position);
}
如果想可以通过按钮删除点位和重置可以加
public void DestroyAllNails()
{
foreach (var nail in nails)
{
Destroy(nail); // 销毁每个nail对象
}
nails.Clear(); // 清除列表中的引用(可选,但有助于避免潜在的内存泄漏)
currentnailNUm = 0; // 重置计数
}
public void DestroyOneNail()
{
if (nails.Count > 0)
{
// 销毁列表中的最后一个元素(即最近创建的Nail)
Destroy(nails[nails.Count - 1]);
nails.RemoveAt(nails.Count - 1); // 从列表中移除已销毁的Nail的引用
currentnailNUm--;
}
}
整体代码:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class MiniMap : MonoBehaviour,IPointerDownHandler
{
public int maxNum;//最大实例化跳转点,可自由设置能标记几个点位
private int currentnailNUm;//记录当前的点位数量
public GameObject nail;//点位
public GameObject Camera;//摄像机
private List<GameObject> nails = new List<GameObject>();//将生成的点做成列表记录
private Vector2 minimapSize;//小地图长和宽
private Vector2 LDPosition;//小地图坐标
public Vector2 FactoryLDPos;//世界场景中的左下角坐标
public Vector2 FactorySize;//世界场景中的长宽
private void Start()
{
minimapSize = new Vector2(GetComponent<RectTransform>().rect.width, GetComponent<RectTransform>().rect.height);//得到小地图的长宽
LDPosition = (Vector2)transform.position - minimapSize/2f;//得到左下角坐标
}
public Vector3 ChangeMinimapPosToWorld( Vector2 ratio,float cameraY )
{
Vector3 WorldPos = new Vector2();
WorldPos.y = cameraY;
WorldPos.x = FactoryLDPos.x + FactorySize.x * ratio.x;
WorldPos.z = FactoryLDPos.y + FactorySize.y * ratio.y;
return WorldPos;
}
public void OnPointerDown(PointerEventData eventData)
{
if (currentnailNUm >= maxNum)
{
return;
}
GameObject temp = Instantiate(nail, eventData.position, Quaternion.identity);
temp.transform.SetParent(transform);
temp.GetComponent<Button>().onClick.AddListener(() =>
{
Vector2 miniMapPos = (Vector2)temp.transform.position - LDPosition;
Vector2 minMapRatio = new Vector2(miniMapPos.x / minimapSize.x, miniMapPos.y / minimapSize.y);
Camera.transform.position = ChangeMinimapPosToWorld(minMapRatio, Camera.transform.position.y);
});
nails.Add(temp);
currentnailNUm++;
Debug.Log(eventData.position);
}
public void DestroyAllNails()
{
foreach (var nail in nails)
{
Destroy(nail); // 销毁每个nail对象
}
nails.Clear(); // 清除列表中的引用(可选,但有助于避免潜在的内存泄漏)
currentnailNUm = 0; // 重置计数
}
public void DestroyOneNail()
{
if (nails.Count > 0)
{
// 销毁列表中的最后一个元素(即最近创建的Nail)
Destroy(nails[nails.Count - 1]);
nails.RemoveAt(nails.Count - 1); // 从列表中移除已销毁的Nail的引用
currentnailNUm--;
}
}
}
总结
该思路其实就跟两个大小不同的矩形,有一个小的矩形A和一个大的矩形B,要想把小的矩形A上的坐标转换到大的矩形B坐标,就通过比例换算过去,新手学习文章,继续加油!