Everything in my game is working is I comment out the following line of code, if I use the code the game becomes unstable and generally crashes withing 1-5 min.
transform.localScale = new Vector3(size, size, size);
I’m doing this to bowling pins so its doing 10 at once, but it seems like I should be able to change the size without crashing the game. I’m at a loss here, as far as I can tell the code is fine, The script is passed its size from one of the 2 following methods.
public string IncreasePinSize(){
float size = UnityEngine.Random.Range (1.2f, 2.5f);
foreach(Pins pin in GameObject.FindObjectsOfType<Pins>()){
pin.ChangeSize(size);
}
return("Giant Pins!");
}
public string DecreasePinSize(){
float size = UnityEngine.Random.Range (0.6f, 0.95f);
foreach(Pins pin in GameObject.FindObjectsOfType<Pins>()){
pin.ChangeSize(size);
}
return("Toy Pins!");
}
public void ChangeSize(float size)
{
transform.localScale = new Vector3(size, size, size);
}
I’m not to sure what else would be relevant code, there is a random chance each turn that this effect will be called when it is the code I posted before to increase or decrease the pin size is called, and that calls the method above. For troubleshooting i’ve already forced it to only call those effects so I know none of the rest of that script is relevant. The error behavior is when the pin size changes the whole game lags for a half second, or unity crashes and gives me the bug report screen. Heres the editor log’s stack trace from last time it crashed
I have another very similar script that changes the size of the ball and thats not having any issues. I’ll put in the entire pin class in case my issue is there and i’m just not able to see it.
using UnityEngine;
using System.Collections;
using System;
public class Pins : MonoBehaviour {
public float standingThreshold = 5f; //how many degrees it can be tilted
public float distanceToRaise = 45f;
public float moveThreshold = 5f;
public AudioClip PinHitPin;
public AudioClip PinHitBall;
private Rigidbody rigidBody;
private AudioSource audioSource;
private float startingPosX;
private float startingPosZ;
private string PinStatus = "None";
PinSetter pinsetter;
void Start () {
rigidBody = GetComponent<Rigidbody>();
audioSource = GetComponent<AudioSource> ();
startingPosX = rigidBody.position.x;
startingPosZ = rigidBody.position.z;
pinsetter = FindObjectOfType<PinSetter>();
}
void Awake()
{
this.GetComponent<Rigidbody>().solverVelocityIterations = 10;
}
//Lifts pins, is called by pinsetter
public void Raise(){
if(IsStanding()){
rigidBody.useGravity = false;
transform.Translate (new Vector3(0, distanceToRaise, 0), Space.World);
}
}
//Lowers pins, is called by pinsetter
public void Lower(){
transform.Translate (new Vector3(0, -distanceToRaise, 0), Space.World);
rigidBody.useGravity = true;
transform.rotation = Quaternion.identity; //Set rotation to 0, lays pin on side
transform.rotation = Quaternion.Euler (-90,0,0);//Correct previous line to make sure pins are all straight after each play.
}
public bool IsStanding(){
if(!HasTilted() && !HasMoved())
{
return true;
}
else{
return false;
}
}
private bool HasMoved()
{
float pinX = transform.position.x;
float pinZ = transform.position.z;
if ((Math.Abs(startingPosX - pinX) < moveThreshold) && (Math.Abs(startingPosZ - pinZ) < moveThreshold)) { return false; }
else { return true; }
}
//We get the current rotation then check to see if it is past the threshold.
private bool HasTilted()
{
//eulerAngles change that into a vector 3
Vector3 rotationInEuler = transform.rotation.eulerAngles;
//Mathf.abs gets absolute position so we dont have to worry about pos or neg, deltaangle calculates shortest ange difference between two angles.
// (e.g. Mathf.DeltaAngle(355, 5) is 10, because 360 is basically the same as 0).
//So if your Pins have a rotation of 0 on the z axis when you start the game, you use 0 as second parameter.
//If your Pin has another rotation while standing, you should of course use that value instead of 0.
if ((Mathf.Abs(Mathf.DeltaAngle(270 - rotationInEuler.x, 0)) < standingThreshold && Mathf.Abs(Mathf.DeltaAngle(rotationInEuler.z, 0)) < standingThreshold))
{
return false;
}
else return true;
}
void OnCollisionEnter(Collision col){
if(col.gameObject.tag == "pin")
{
audioSource.clip = PinHitPin;
}
else if (col.gameObject.tag == "ChildBall")
{
audioSource.clip = PinHitBall;
if (ThingTracker.firstPin)
{
ThingTracker.firstPin = false;
pinsetter.SlowTime();
}
//Add force when pin is hit to make physics apply more realisticly.
Vector3 HitForce = (transform.position - col.contacts[0].point).normalized * col.rigidbody.mass * 2.5f;
rigidBody.AddForce(HitForce, ForceMode.Impulse);
}
audioSource.Play ();
}
//fix issues cause by nice bowling mode
public void DefaultPins(){
if (rigidBody.isKinematic) {
rigidBody.isKinematic = false;
PinStatus = "BoardwalkPins";
}
if (rigidBody.drag != 0) {
rigidBody.drag = 0;
rigidBody.angularDrag = 0.05f;
PinStatus = "IncreasePinDrag";
}
}
//fix issues cause by nice bowling mode
public void NicePins()
{
if (PinStatus == "BoardwalkPins") {
rigidBody.isKinematic = true;
}
if (PinStatus == "IncreasePinDrag") {
rigidBody.drag = 15f;
rigidBody.angularDrag = 30f;
}
}
//Change size of pins
public void ChangeSize(float size)
{
//transform.localScale = new Vector3(size, size, size);
}
}
I was wondering if the profiler may give a clue here but it may just show it is a physics calc. But could be worth a look.
Maybe other things to play around with are:
o what if you only reduce pin size (size < 1)
o or only increased pin size (size > 1) to see if it is a particular direction causing it.
o What happens if there is only one pin (as there is presumably only 1 ball that works ok), does the problem, still occur then?
o What happens if you start the game with a different start size - i.e. is the size the issue or just the changing of the size causing it?
o Try creating a brand new scene that contains only a simple ground plane and 1 pin - can that be rescaled ok? If so, then try the full 10 pins. Then just keep adding in stuff from the original scene to see if you can find clues that way.
Thank you, I’ll try some of that, otherwise i’m looking at possibly just making another set of prefab pins that are larger and instantiating them instead of instantiating the normal pins then making them larger.
Are you possibly scaling a collider to some obscenely small size and the physics engine is throwing a fit over it? I would also check if scaling the object in the middle of an OnCollisionXYZ callback might be the root issue as well, as it may be forcing a rebuild of internal data while iterating over that data.