C# Unity 2D-放大=确定,缩小=关闭
我希望有人能帮忙。我正在尝试创建一个小脚本,可以放大到我的播放器,然后进行切换。 放大效果很好,但当我尝试缩小时它不起作用,它会卡住。我创建了一个bool,以确保它只在需要时运行代码,我想知道这是否是导致错误的原因C# Unity 2D-放大=确定,缩小=关闭,c#,unity3d,C#,Unity3d,我希望有人能帮忙。我正在尝试创建一个小脚本,可以放大到我的播放器,然后进行切换。 放大效果很好,但当我尝试缩小时它不起作用,它会卡住。我创建了一个bool,以确保它只在需要时运行代码,我想知道这是否是导致错误的原因 using UnityEngine; using System.Collections; public class CameraZoom : MonoBehaviour { public float zoom = 10f; public float normal = 3.4713
using UnityEngine;
using System.Collections;
public class CameraZoom : MonoBehaviour
{
public float zoom = 10f;
public float normal = 3.471398f;
public float smooth = 5f;
private bool isZoomed = false;
public Camera cam;
public GameObject player;
// lock the camera settings
public float LockedX = 0f;
public float LockedY = 0f;
public float LockedZ = 0f;
private bool hasBeenZoomed = false;
Vector3 targetPos;
private Transform playerTransform;
// Use this for initialization
void Start()
{
targetPos = transform.position;
playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown("z")) { isZoomed = !isZoomed; }
if (isZoomed == true)
{
ZoomInToPlayer();
hasBeenZoomed = true;
}
else
{
if (hasBeenZoomed)
{
ZoomOutFromPlayer();
hasBeenZoomed = false;
}
}
}
void ZoomInToPlayer()
{
// By default the target x and y coordinates of the camera are it's current x and y coordinates.
float targetX = transform.position.x;
float targetY = transform.position.y;
// ... the target x coordinate should be a Lerp between the camera's current x position and the player's current x position.
targetX = Mathf.Lerp(transform.position.x, playerTransform.position.x, smooth * Time.deltaTime);
//Debug.Log("player x is " + playerTransform.position.x + " and TargetX is " + targetX);
// ... the target y coordinate should be a Lerp between the camera's current y position and the player's current y position.
targetY = Mathf.Lerp(transform.position.y, playerTransform.position.y, smooth * Time.deltaTime);
//Debug.Log("player y is " + playerTransform.position.y+ " and TargetY is " + targetY);
// Set the camera's position to the target position with the same z component.
cam.transform.position = new Vector3(targetX, targetY, transform.position.z);
// Change the size of the camera viewport
cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, zoom, Time.deltaTime * smooth);
}
void ZoomOutFromPlayer()
{
// By default the target x and y coordinates of the camera are it's current x and y coordinates.
float targetX;
float targetY;
// Change the size of the camera viewport
cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, normal, Time.deltaTime * smooth);
// ... the target x coordinate should be a Lerp between the camera's current x position and the original x position.
targetX = Mathf.Lerp(transform.position.x, LockedX, smooth * Time.deltaTime);
// ... the target y coordinate should be a Lerp between the camera's current y position and the original y position.
targetY = Mathf.Lerp(transform.position.y, LockedY, smooth * Time.deltaTime);
// Set the camera's position to the target position with the same z component.
cam.transform.position = new Vector3(targetX, targetY, transform.position.z);
}
}
您的方法
ZoomInToPlayer
和ZoomOutFromPlayer
的编写方式建议在放大/缩小动画期间,每帧调用一次。但是,ZoomOutFromPlayer
将只被调用一次,因为Update
在调用ZoomOutFromPlayer
时,hasbeenzomed
将立即设置为false
你在这里要做的,本质上,是一个简单的过程。我建议进一步研究这种设计模式——它将帮助您发现这些问题的根源,并以更好的方式构建代码
在这种特殊情况下,在设计代码时防止此问题的一个好方法是在编写方法时为自己编写类似于“API文档”的内容。对于ZoomOutFromPlayer
,其内容如下:
在要执行缩小动画时调用每一帧,直到动画完成
在您编写(和阅读)这样的描述之后,您应该立即注意到一个红色标志——“直到动画完成”?因此,调用此方法的代码应该在单独的机制中跟踪动画是否完成?错误地使用这种方法不是很容易吗?这就是这里发生的事情
相反,您可以创建两个不同的方法,ZoomInUpdate
和ZoomOutUpdate
,其描述如下:
当相机应该缩小/放大时,调用每一帧
通过这种方式,使用这种方法要容易得多,并且您可以使用hasBeenZoomed
out安全地抛出额外的逻辑。只要在每一帧调用这些方法,并确保(在这些方法中)它们以一定的速度更改相机设置(如果需要更改这些设置),否则什么也不做。试试这个
using UnityEngine;
using System.Collections;
public class CameraZoom : MonoBehaviour
{
public float zoom = 10f;
public float normal = 3.471398f;
public float smooth = 5f;
private bool isZoomed = false;
private bool isZoomFinished = true; // the animation zoom is over ?
public Camera cam;
public GameObject player;
public float LockedX = 0f;
public float LockedY = 0f;
public float LockedZ = 0f;
private bool hasBeenZoomed = false;
Vector3 targetPos;
private Transform playerTransform;
void Start()
{
targetPos = transform.position;
playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update()
{
if (Input.GetKeyDown("z") && isZoomFinished) {
isZoomed = !isZoomed;
isZoomFinished = false;
}
if (isZoomed && !isZoomFinished)
{
ZoomInToPlayer();
}
else if (!isZoomed && !isZoomFinished)
{
ZoomOutFromPlayer()
}
}
float delta = 0;
void ZoomInToPlayer()
{
delta += smooth * Time.deltaTime;
//Cam size
cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, zoom, delta);
//Cam pos
float targetX = transform.position.x;
float targetY = transform.position.y;
targetX = Mathf.Lerp(transform.position.x, playerTransform.position.x, delta);
targetY = Mathf.Lerp(transform.position.y, playerTransform.position.y, delta);
cam.transform.position = new Vector3(targetX, targetY, transform.position.z);
// is animation over ?
if(delta >= 1) {
isZoomFinished = true;
delta = 0;
}
}
void ZoomOutFromPlayer()
{
delta += smooth * Time.deltaTime;
//Cam size
cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, normal, delta);
//Cam pos
float targetX;
float targetY;
targetX = Mathf.Lerp(transform.position.x, LockedX, delta);
targetY = Mathf.Lerp(transform.position.y, LockedY, delta);
cam.transform.position = new Vector3(targetX, targetY, transform.position.z);
// is animation over ?
if(delta >= 1) {
isZoomFinished = true;
delta = 0;
}
}
}
每次编写
if(something==true)
时,最好用if(something)
替换它。这很好,谢谢。那么,为什么它不缩小到正确的位置,如LockedX/Y变量中所示的0,0。有没有一种方法可以同时缩放和移动,即变换和改变图像大小?愚蠢的我,这是增量变量,一旦所有人都得到相同的增量变量,他们就在同一时间线上工作。现在工作,谢谢。现在,我需要做的就是找出如何降低动画的速度,同时仍然允许识别z键。“平滑”设置为1.1似乎是目前为止最好的设置,但在z键被识别之前,它放大后似乎要等待很长时间。