2016-09-18 2 views
0

안녕하세요 개발자이 질문은 전에 물어 보았지만 문제에 대한 해결책을 찾지 못했습니다. 그 답은, 먼저 화합의 초심자라고 말씀 드리고 싶습니다. P, 여기에 제 문제가 있습니다. 저는 벽돌 브레이커 게임을 만들고 있습니다. 내가하려고하는 것은"Unity3D"인덱스 범위를 벗어남 예외 : 배열 인덱스가 범위를 벗어났습니다. (맞았을 때 스프라이트를 변경하려고 시도합니다.)

public int maxHits; 
public int timesHit; 
private LevelManager levelManager; 
public Sprite[] hitSprites; 

void Start() { 
    timesHit = 0; 
    levelManager = GameObject.FindObjectOfType<LevelManager>(); 
} 

void OnCollisionEnter2D(Collision2D collision) { 
    print ("collison"); 
    timesHit++; 
} 

    // Update is called once per frame 
void Update() { 
    if (timesHit >= maxHits) { 
     Destroy (gameObject); 
    } else { 
     LoadSprite(); 
    } 
    } 

void LoadSprite(){ 
     int spriteIndex = timesHit - 1; 
     this.GetComponent<SpriteRenderer>().sprite = hitSprites  [spriteIndex]; 
    } 
} 

을하지만 난이 오류 받고 있어요 : 그것이 공을 당한다 벽돌은, 그래서이 스크립트를 사용하고 수행하는 IndexOutOfRangeException: Array index is out of range. Brick.LoadSprite() (at Assets/Scripts/Brick.cs:34)

을 나는 그것을 모든 프레임을 받고 있어요! 에스 o 게임 장면이 너무 느려서 더 이상 게임을 테스트 할 수 없습니다. 제 잘못을 고치고 해결하는 방법을 제발 가르쳐 주실 수 있습니까? 제게 실수를 더 배우고 다시하지 않는 코스로 안내하면 도움이 될 수 있습니다.

답변

0

시간이 0에서 시작하고 스프라이트를로드 할 때 1에서 -1을 빼면이 현상이 발생합니다. 다음 줄의 LoadSprite에서는 hitSprites 배열에 인덱스 -1 (hitSprites [-1])에 액세스하려고 시도합니다. 물론 범위를 벗어납니다.

적어도 인덱스 유효성 검사를 위해 유효성 검사를 추가 할 것입니다.

0

당신이하고있는 일을 알 수는 없지만> = hitSprites 길이의 색인에 액세스하고 있기 때문에 오류가 발생했습니다.

변수가 사용되기 전에 hitSprites 길이보다 작은 지 확인해야합니다.

LoadSprite 기능은 다음과 같아야합니다

void LoadSprite() 
{ 
    int spriteIndex = 0; 

    //Don't decrement if timesHit is 0 
    if (timesHit > 0) 
    { 
     spriteIndex = timesHit - 1; 
    } 
    else 
    { 
     spriteIndex = timesHit; 
    } 

    //Return/Exit function if spriteIndex is equals or more than hitSprites length 
    if (spriteIndex > hitSprites.Length - 1) 
    { 
     return; 
    } 
    this.GetComponent<SpriteRenderer>().sprite = hitSprites[spriteIndex]; 
} 
0

당신은 0보다 작은 (첫 번째 배열 인덱스)를 이동하지 spriteIndex 클램프 1 (마지막 배열 인덱스) 감소 hitSprites.Length 이상 할 필요가있다.

void LoadSprite(){ 
     int spriteIndex = Mathf.Clamp(timesHit - 1, 0, hitSprites.Length - 1); 
     this.GetComponent<SpriteRenderer>().sprite = hitSprites [spriteIndex]; 
    } 
} 

팁 : 는 나중에 사용하기 위해 깨어에 업데이트 ... 프리 페치의 모든 구성 요소를 너무 많이 GetComponent를 호출하지 말아.

private SpriteRenderer _spriteRenderer; 

void Awake() 
{ 
_spriteRenderer = GetComponent<SpriteRenderer>(); 
} 
0

이 @Programmer @ user2867426 주먹 댄 - 쿡 @ 내가 귀하의 답변에 대한 여러분 모두 감사드립니다, 내가 그렇게들로부터 많은 것을 배웠다, 큰 당신을 감사합니다! 음, 실수로 실수를 저질렀습니다. 롤. 난 내 코드를 최적화 할 때 내가 만약 내가이 사용하던 것으로 나타났습니다 업데이트의 조건() 내가 OnCollisionEnter2D()에 직접 사용할 수있는 동안 : 몰라요

if (timesHit >= maxHits) { 
    Destroy (gameObject); 
} else { 
    LoadSprite(); 
} 

을 어떻게 든 그건 내 문제를 해결 어떻게, 어쩌면 문제는 그것이 매 프레임마다 불려서 지금은 그렇지 않다는 것입니다! 너희들이 나에게 어떻게 움직일 수 있는지 설명해 주겠다. 업데이트()에서 조건이 문제를 해결하면 정말 고마워. ^^ 다시 한번 감사드립니다.

+0

대답을 수락하면 대답을 수락하지 못합니다 .... 질문에 대답하려면 'OnCollisionEnter2D'에서 호출하는 것은 실제 적중이있을 때만 호출하기 때문입니다. 하지만 코드를 Update 함수로 옮기면 히트 여부와 관계없이 초당 60 회 또는 모든 프레임이 호출됩니다. 해피 코딩! – Programmer

+0

@Programmer aaah ok 나는 지금 더 잘 이해하고있다. 그래서 어떤 히트가 일어나기 전에 일어난 일은 시간 = 0이었다. 그리고 spriteIndex = timesHit - 1; spriteIndex는 -1을 얻었고 그게 문제를 일으키는 원인이었습니다! LoadSprite() 메서드 상단에 "if (timeshit <1) return;"을 추가하면 spriteIndex의 값이 -1이되지 않습니다. D –

+0

예, 맞습니다. 또한 길이가'hitSprites'의 길이보다 길거나 같지 않은지 확인해야합니다. 'hitSprites.Length - 1'. 나는 이것을 나의 대답에서 설명했다. – Programmer