它使附加的游戏对象沿鼠标光标方向从玩家(出于某种原因)扭曲这么多单位,并且还转向朝向该方向的右侧(出于某种原因)。
下面的 cmets 中解释了各个部分:
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;