Camera.ScreenToWorldPoint() API个人理解 和 RTS游戏点击移动的实现思路
ScreenToWorldPoint 官方定义
public Vector3 ScreenToWorldPoint(Vector3 position); Description Transforms position from screen space into world space. Screenspace is defined in pixels. The bottom-left of the? screen is (0,0); the right-top is (pixelWidth,pixelHeight). The z position is in world units from the camera.
大体意思就是将一个变换组件的位置从屏幕坐标转化为世界坐标(单位是像素),屏幕的左下方是原点 (0,0),右上方的坐标为(width,height)单位为像素,z轴表示的是该位置到摄像机的距离
实际测试 这个API在使用时需要对Input.MousePosition加上一个z轴坐标才会有效,因为MousePosition返回的三维向量z轴值为0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class test : MonoBehaviour {
private Camera m_camera;
//引入的预制体
public GameObject g;
void Start () {
//获取主摄像机的引用
m_camera = Camera.main;
}
void Update () {
if (Input.GetMouseButtonDown(0))
{
//获取预制体的变换组件并改变位置为鼠标点击位置转化后的世界坐标
g.GetComponent<Transform>().position= m_camera.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, 10));
//在变化后的位置生成一个预制体
Instantiate(g, m_camera.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, 5)), Quaternion.identity);
}
}
}
z轴赋值为5
z轴赋值为50
总结
在使用时需要加上一个 Vector3(0,0,z)否则转换后获取的坐标就是摄像机所在的位置
z的值越大,获取的坐标离摄像机越远,x和y的值变化幅度也越大
TPS游戏人物点击移动 构想
起初想用ScreenToWorldPoint方法实现这一功能,但是实际发现这个方法并不能满足需求,因为这个方法返回的位置y轴始终是变化的,而游戏要求人物应该是贴着地面走
使用射线的碰撞的方法可以完成这一需求,射线碰撞返回碰撞的位置,给人物的Transfrom.position赋值这个位置即可
实现 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RAY : MonoBehaviour {
private Camera m_camera;
//用来存储碰撞物体的信息
private RaycastHit hit;
//定义射线存储ScreenPointToRay返回的值
private Ray ray;
public GameObject g;
void Start () {
//获取主摄像机的引用
m_camera = Camera.main;
}
void Update () {
if (Input.GetMouseButtonDown(0))
{
//获取目标物体的实际y轴长度
float y=g.GetComponent<MeshFilter>().mesh.bounds.size.y*g.transform.localScale.y;
////将当前鼠标点击的位置作为终点产生一条射线
ray = m_camera.ScreenPointToRay(Input.mousePosition);
////Physics.Raycast(Ray,out RaycastHit) RaycastHit存储与射线发生碰撞物体的信息
if (Physics.Raycast(ray, out hit))
{
//销毁碰撞物体
//Destroy(hit.collider.gameObject);
Debug.Log(hit.collider.name);
//如果点击自己不改变位置,否则就会越来越高
if (hit.collider.gameObject.name != "Cube")
{
g.GetComponent<Transform>().position = hit.point + new Vector3(0, y / 2, 0);
//加上高度的一半,使物体始终处于地面上部
}
}
}
}
}
<
Unity3D进阶(二)
TPS射击游戏实战开发(终)
>