【发布时间】:2016-10-20 22:45:37
【问题描述】:
在 Unity2D 中,我制作了一个脚本,在相机可以看到结尾之前重复背景精灵。
这是我的代码:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof(SpriteRenderer))]
public class Tiling : MonoBehaviour {
public int offsetX = 2; // the offset so that we don't get any weird errors
// these are used for checking if we need to instantiate stuff
public bool hasARightBuddy = false;
public bool hasALeftBuddy = false;
public bool reverseScale = false; // used if the object is not tilable
private float spriteWidth = 0f; // the width of our element
private Camera cam;
private Transform myTransform;
private float localSc;
void Awake () {
cam = Camera.main;
myTransform = transform;
localSc = transform.localScale.x;
}
// Use this for initialization
void Start () {
SpriteRenderer sRenderer = GetComponent<SpriteRenderer>();
spriteWidth = sRenderer.sprite.bounds.size.x * transform.localScale.x;
}
// Update is called once per frame
void Update () {
// does it still need buddies? If not do nothing
if (hasALeftBuddy == false || hasARightBuddy == false) {
// calculate the cameras extend (half the width) of what the camera can see in world coordinates
float camHorizontalExtend = cam.orthographicSize * Screen.width/Screen.height;
// calculate the x position where the camera can see the edge of the sprite (element)
float edgeVisiblePositionRight = (myTransform.position.x + spriteWidth/2) - camHorizontalExtend;
float edgeVisiblePositionLeft = (myTransform.position.x - spriteWidth/2) + camHorizontalExtend;
// checking if we can see the edge of the element and then calling MakeNewBuddy if we can
if (cam.transform.position.x >= edgeVisiblePositionRight - offsetX && hasARightBuddy == false)
{
MakeNewBuddy (1);
hasARightBuddy = true;
}
else if (cam.transform.position.x <= edgeVisiblePositionLeft + offsetX && hasALeftBuddy == false)
{
MakeNewBuddy (-1);
hasALeftBuddy = true;
}
}
}
// a function that creates a buddy on the side required
void MakeNewBuddy (int rightOrLeft) {
// calculating the new position for our new buddy
Vector3 newPosition = new Vector3 (myTransform.position.x + spriteWidth * rightOrLeft, myTransform.position.y, myTransform.position.z);
// instantating our new body and storing him in a variable
Transform newBuddy = Instantiate (myTransform, newPosition, myTransform.rotation) as Transform;
newBuddy.parent = myTransform.parent;
// if not tilable let's reverse the x size on our object to get rid of missmatches
if (reverseScale == true) {
newBuddy.localScale = new Vector3 (localSc*-1 , 1, 1);
}
if (rightOrLeft == 1) { //if this function was called to make a right buddy (1)
newBuddy.GetComponent<Tiling>().hasALeftBuddy = true;
}
else { //else we just made a left buddy, so it has a right copy
newBuddy.GetComponent<Tiling>().hasARightBuddy = true;
}
}
现在,脚本已附加到背景精灵,并且可以正常工作。
您会看到有一个 bool reverseScale 来反转图像。
这是因为如果图像不可重复,(结束和开始在像素级别上不匹配)我们可以通过还原 (* -1) x 比例来镜像它。
奇怪的是,如果我在禁用 reverseScale 的情况下启动它,一切都会按我说的那样工作。 如果我启用 reverseScale,它就会变得一团糟。无限循环的重叠、严重缩放的精灵,导致游戏崩溃。
我错过了什么?最坏的情况(但仍然不应该发生),代码 sn-p 应该生成一个不匹配的图像,为什么它会破坏程序?
编辑:
感谢 Enfyve 的回答,我找到了解决方案。出于某种原因,我正在翻转整个图形组件的比例,而不是一个单一的。应该使用 flipX 字段。此外,每两个瓷砖只需翻转一个,以避免不匹配。
【问题讨论】:
-
这个类不一定有任何失控的循环,所以它一定是在其他地方导致了问题。另外,您获得了
newBuddy的Tiling组件,但是您是否首先添加了该组件? (这里没看到)