三角学 + 角度 - 围绕玩家旋转并面向鼠标方向的对象
Trigonometry + Angles - Object rotating around player and facing mouse direction
我不明白这段代码是如何工作的,我正在寻求解释。此代码位于更新函数内,不断更新对象位置。
我所说的“面向鼠标方向”是指该物体就像地球围绕太阳公转一样,但是您可以选择它当前位于它围绕太阳的自转线上的位置。
public GameObject player;
private Vector3 v3Pos;
private float angle;
private readonly float distance = 0.16f;
private void Update()
{
v3Pos = Input.mousePosition;
v3Pos.z = (player.transform.position.z -
Camera.main.transform.position.z);
v3Pos = Camera.main.ScreenToWorldPoint(v3Pos);
v3Pos -= player.transform.position;
angle = Mathf.Atan2(v3Pos.y, v3Pos.x) * Mathf.Rad2Deg;
if (angle < 0.0f) { angle += 360.0f; }
transform.localEulerAngles = new Vector3(0, 0, angle);
float xPos = Mathf.Cos(Mathf.Deg2Rad * angle) * distance;
float yPos = Mathf.Sin(Mathf.Deg2Rad * angle) * distance;
transform.localPosition = new Vector3(player.transform.position.x +
xPos * 4, player.transform.position.y + yPos * 4, 0);
}
我在一段视频中发现了这段代码,它使一个物体(如枪)围绕玩家旋转并同时跟随鼠标,但我不明白它是如何工作的。它是如何工作的?另外,我不知道视频在哪里,但如果需要我会找到它。
它使附加的游戏对象在玩家鼠标光标的方向上扭曲这么多单位(由于某种原因在局部),并且还转向面向该方向的右侧(由于某种原因在局部)。
个别部分在下面的评论中解释:
public GameObject player;
private Vector3 v3Pos;
private float angle;
private readonly float distance = 0.16f;
private void Update()
{
// mouse position in screen space
// current value = (mouse x, mouse y, 0) )
Vector3 v3Pos = Input.mousePosition;
// sets the z coordinate to be the difference from the camera to the player
// along the forward world axis.
// current value = (mouse x, mouse y, camera->player distance along forward)
v3Pos.z = (player.transform.position.z - Camera.main.transform.position.z);
// v3Pos now means the position of the cursor, projected onto plane the player
// is on parallel to camera plane
// This means it's a world space positioning of the mouse
v3Pos = Camera.main.ScreenToWorldPoint(v3Pos);
// v3Pos now means the direction from the player to the mouse position
// in world space.
// Despite the name, now a direction, not a position!
v3Pos -= player.transform.position;
// finds the signed angle from right to the direction v3Pos represents.
// in the range (-180, 180]. positive = counterclockwise
angle = Mathf.Atan2(v3Pos.y, v3Pos.x) * Mathf.Rad2Deg;
// converts negative angle into an equivalent positive angle.
if (angle < 0.0f) { angle += 360.0f; }
// sets the forward axis angle of the transform this
// MonoBehaviour is attached to as the same angle.
// Since we measured from the right to the direction of the mouse,
// this turns the right side to face the mouse.
// This is done in local space for some reason, can't tell from code.
transform.localEulerAngles = new Vector3(0, 0, angle);
// finds x and y coordinates of a point in the same direction as
// v3Pos the mouse from the player but at distance
// Could use v3Pos but with a z=0, normalized then * distance but
// recalculating with trig works too.
// basic trig refresher
// cos of angle from right gives unit circle x coordinate
// sin of angle from right gives unit circle y coordinate
float xPos = Mathf.Cos(Mathf.Deg2Rad * angle) * distance;
float yPos = Mathf.Sin(Mathf.Deg2Rad * angle) * distance;
// sets the player's local position to be the position of the player
// adjusted by the direction and distance of the point.
// Also done in local space, can't tell why from code.
// Weird to use something else's world position as the local position
// for something else.
transform.localPosition = new Vector3(player.transform.position.x
+ xPos * 4, player.transform.position.y + yPos * 4, 0);
}
上面提到的替代计算可以这样完成:
Vector3 v3Pos = Input.mousePosition;
v3Pos.z = (player.transform.position.z - Camera.main.transform.position.z);
v3Pos = Camera.main.ScreenToWorldPoint(v3Pos);
v3Pos -= player.transform.position;
angle = Mathf.Atan2(v3Pos.y, v3Pos.x) * Mathf.Rad2Deg;
if (angle < 0.0f) { angle += 360.0f; }
transform.eulerAngles = new Vector3(0, 0, angle);
Vector3 v3DirFlat = v3Pos;
v3DirFlat.z = 0f;
// keeping both * distance and * 4
v3DirFlat = v3DirFlat.normalized * distance * 4;
transform.position = player.transform.position + v3DirFlat;
步骤是
// Get the mouse position on the screen
v3Pos = Input.mousePosition;
// Bring that point down until it is level with the player
v3Pos.z = (player.transform.position.z - Camera.main.transform.position.z);
// Find that point in world space coordinates
v3Pos = Camera.main.ScreenToWorldPoint(v3Pos);
// Find the vector from the player to that point
v3Pos -= player.transform.position;
// Calculate the angle between that vector and the X axis
angle = Mathf.Atan2(v3Pos.y, v3Pos.x) * Mathf.Rad2Deg;
// ensure the values are between 0 and 360
if (angle < 0.0f) { angle += 360.0f; }
// Set the item's rotation to that angle, so it faces the right direction
transform.localEulerAngles = new Vector3(0, 0, angle);
// Find the new position of the item on the orbit circle
float xPos = Mathf.Cos(Mathf.Deg2Rad * angle) * distance;
float yPos = Mathf.Sin(Mathf.Deg2Rad * angle) * distance;
// Set the item to it's new position
transform.localPosition = new Vector3(player.transform.position.x + xPos * 4, player.transform.position.y + yPos * 4, 0);
我不确定为什么最后一步的坐标乘以 4,它们应该已经位于半径为 distance
的圆上
我不明白这段代码是如何工作的,我正在寻求解释。此代码位于更新函数内,不断更新对象位置。
我所说的“面向鼠标方向”是指该物体就像地球围绕太阳公转一样,但是您可以选择它当前位于它围绕太阳的自转线上的位置。
public GameObject player;
private Vector3 v3Pos;
private float angle;
private readonly float distance = 0.16f;
private void Update()
{
v3Pos = Input.mousePosition;
v3Pos.z = (player.transform.position.z -
Camera.main.transform.position.z);
v3Pos = Camera.main.ScreenToWorldPoint(v3Pos);
v3Pos -= player.transform.position;
angle = Mathf.Atan2(v3Pos.y, v3Pos.x) * Mathf.Rad2Deg;
if (angle < 0.0f) { angle += 360.0f; }
transform.localEulerAngles = new Vector3(0, 0, angle);
float xPos = Mathf.Cos(Mathf.Deg2Rad * angle) * distance;
float yPos = Mathf.Sin(Mathf.Deg2Rad * angle) * distance;
transform.localPosition = new Vector3(player.transform.position.x +
xPos * 4, player.transform.position.y + yPos * 4, 0);
}
我在一段视频中发现了这段代码,它使一个物体(如枪)围绕玩家旋转并同时跟随鼠标,但我不明白它是如何工作的。它是如何工作的?另外,我不知道视频在哪里,但如果需要我会找到它。
它使附加的游戏对象在玩家鼠标光标的方向上扭曲这么多单位(由于某种原因在局部),并且还转向面向该方向的右侧(由于某种原因在局部)。
个别部分在下面的评论中解释:
public GameObject player;
private Vector3 v3Pos;
private float angle;
private readonly float distance = 0.16f;
private void Update()
{
// mouse position in screen space
// current value = (mouse x, mouse y, 0) )
Vector3 v3Pos = Input.mousePosition;
// sets the z coordinate to be the difference from the camera to the player
// along the forward world axis.
// current value = (mouse x, mouse y, camera->player distance along forward)
v3Pos.z = (player.transform.position.z - Camera.main.transform.position.z);
// v3Pos now means the position of the cursor, projected onto plane the player
// is on parallel to camera plane
// This means it's a world space positioning of the mouse
v3Pos = Camera.main.ScreenToWorldPoint(v3Pos);
// v3Pos now means the direction from the player to the mouse position
// in world space.
// Despite the name, now a direction, not a position!
v3Pos -= player.transform.position;
// finds the signed angle from right to the direction v3Pos represents.
// in the range (-180, 180]. positive = counterclockwise
angle = Mathf.Atan2(v3Pos.y, v3Pos.x) * Mathf.Rad2Deg;
// converts negative angle into an equivalent positive angle.
if (angle < 0.0f) { angle += 360.0f; }
// sets the forward axis angle of the transform this
// MonoBehaviour is attached to as the same angle.
// Since we measured from the right to the direction of the mouse,
// this turns the right side to face the mouse.
// This is done in local space for some reason, can't tell from code.
transform.localEulerAngles = new Vector3(0, 0, angle);
// finds x and y coordinates of a point in the same direction as
// v3Pos the mouse from the player but at distance
// Could use v3Pos but with a z=0, normalized then * distance but
// recalculating with trig works too.
// basic trig refresher
// cos of angle from right gives unit circle x coordinate
// sin of angle from right gives unit circle y coordinate
float xPos = Mathf.Cos(Mathf.Deg2Rad * angle) * distance;
float yPos = Mathf.Sin(Mathf.Deg2Rad * angle) * distance;
// sets the player's local position to be the position of the player
// adjusted by the direction and distance of the point.
// Also done in local space, can't tell why from code.
// Weird to use something else's world position as the local position
// for something else.
transform.localPosition = new Vector3(player.transform.position.x
+ xPos * 4, player.transform.position.y + yPos * 4, 0);
}
上面提到的替代计算可以这样完成:
Vector3 v3Pos = Input.mousePosition;
v3Pos.z = (player.transform.position.z - Camera.main.transform.position.z);
v3Pos = Camera.main.ScreenToWorldPoint(v3Pos);
v3Pos -= player.transform.position;
angle = Mathf.Atan2(v3Pos.y, v3Pos.x) * Mathf.Rad2Deg;
if (angle < 0.0f) { angle += 360.0f; }
transform.eulerAngles = new Vector3(0, 0, angle);
Vector3 v3DirFlat = v3Pos;
v3DirFlat.z = 0f;
// keeping both * distance and * 4
v3DirFlat = v3DirFlat.normalized * distance * 4;
transform.position = player.transform.position + v3DirFlat;
步骤是
// Get the mouse position on the screen
v3Pos = Input.mousePosition;
// Bring that point down until it is level with the player
v3Pos.z = (player.transform.position.z - Camera.main.transform.position.z);
// Find that point in world space coordinates
v3Pos = Camera.main.ScreenToWorldPoint(v3Pos);
// Find the vector from the player to that point
v3Pos -= player.transform.position;
// Calculate the angle between that vector and the X axis
angle = Mathf.Atan2(v3Pos.y, v3Pos.x) * Mathf.Rad2Deg;
// ensure the values are between 0 and 360
if (angle < 0.0f) { angle += 360.0f; }
// Set the item's rotation to that angle, so it faces the right direction
transform.localEulerAngles = new Vector3(0, 0, angle);
// Find the new position of the item on the orbit circle
float xPos = Mathf.Cos(Mathf.Deg2Rad * angle) * distance;
float yPos = Mathf.Sin(Mathf.Deg2Rad * angle) * distance;
// Set the item to it's new position
transform.localPosition = new Vector3(player.transform.position.x + xPos * 4, player.transform.position.y + yPos * 4, 0);
我不确定为什么最后一步的坐标乘以 4,它们应该已经位于半径为 distance