Optimization script doesn`t work. I made a script to optimize my game in unity, when the player is standing, everything is fine, But once it starts to go... Framerate Per Second starts to decrease to zero, tell me what should I do? After all, the player does not perform heavy operations, how can this load something? (I tried OnBecameVisible and OnBecameInvisible they don't work)
~Scripts~
using UnityEngine;
[RequireComponent(typeof(ObjectParameters))]
public class ObjectManager : MonoCache
{
public SpriteRenderer[] spriteRenderers;
[Space]
public ObjectParameters objectParameters;
[Space]
[SerializeField] bool freezeRotation;
bool isBuilded;
[Space]
public bool usingDragging = true;
[Space]
[SerializeField] bool usingRigidBody;
Rigidbody2D rb2D;
float gS;
[Space]
[SerializeField] bool usingSheetDrop;
SheetDrop sheetDrop;
void Start()
{
rb2D = GetComponent<Rigidbody2D>();
objectParameters = GetComponent<ObjectParameters>();
sheetDrop = GetComponent<SheetDrop>();
if (usingRigidBody == true)
{
rb2D.constraints = RigidbodyConstraints2D.FreezeAll;
gS = rb2D.gravityScale;
}
if (usingSheetDrop == true)
{
sheetDrop.enabled = false;
}
objectParameters.enabled = false;
for (int i = 0; i < spriteRenderers.Length; i++)
{
spriteRenderers[i].enabled = false;
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "PlayerDrawing")
{
if (usingRigidBody == true)
{
if (rb2D == null)
{
rb2D = GetComponent<Rigidbody2D>();
}
if (freezeRotation == false)
{
rb2D.constraints = RigidbodyConstraints2D.None;
}
}
if (usingSheetDrop == true)
{
sheetDrop.enabled = true;
}
objectParameters.enabled = true;
for (int i = 0; i < spriteRenderers.Length; i++)
{
spriteRenderers[i].enabled = true;
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.tag == "PlayerDrawing")
{
if (usingRigidBody == true)
{
if (rb2D == null)
{
rb2D = GetComponent<Rigidbody2D>();
}
if (rb2D.constraints != RigidbodyConstraints2D.FreezeAll || rb2D.bodyType != RigidbodyType2D.Kinematic)
{
rb2D.constraints = RigidbodyConstraints2D.FreezeAll;
}
}
}
if (usingSheetDrop == true)
{
sheetDrop.enabled = false;
}
objectParameters.enabled = false;
for (int i = 0; i < spriteRenderers.Length; i++)
{
spriteRenderers[i].enabled = false;
}
}
}
and ObjectParameters
using UnityEngine;
public class ObjectParameters : MonoCache
{
public Dragging dragging;
public Rigidbody2D rb;
public Vector3 position;
public Quaternion rotation;
ObjectManager objectManager;
Transform transform_;
void Start()
{
objectManager = GetComponent<ObjectManager>();
transform_ = transform;
rb = GetComponent<Rigidbody2D>();
}
public override void OnTick()
{
position = transform_.position;
rotation = transform_.rotation;
}
}
I wanted the script to work like this: When an object touches the Player Drawing, it turns on physic and SpriteRenderer, otherwise everything would happen in reverse. BUT IT DOESN'T WORK.
help please
Make sure you don't have any exceptions spamming into the console when you walk.
Also make sure to use the Profiler to see what method-calls are using the most of your framerate, you might have to turn on the deep profiler to see the exact methods.
Related
I've made this code myself so I'm not sure what I've done wrong, I have a colider for my sword but whenever I get in range and swing my whole unity crashes
using System;
using UnityEngine;
public class Attack : MonoBehaviour
{
private CircleCollider2D cc2;
private float x = 3;
private Boolean timer = true;
private Boolean hasAttacked = false;
private void Start()
{
cc2.isTrigger = true;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if(hasAttacked == false)
{
hasAttacked = true;
if (Input.GetKey(KeyCode.Mouse0))
{
while (timer == true)
{
x -= Time.deltaTime;
}
while (x >= 1)
if (collision.gameObject.name == "Enemy")
{
Destroy(GameObject.Find("Enemy"));
}
if (x == 0)
{
hasAttacked = false;
x = 3;
}
}
}
}
}
The Player is the parent of the sword if it makes a difference
It could be that they both try to destroy each other because the enemy is made to destroy the player
The problem is with the while (timer == true). If it's true, then it will stuck in there. Also when you decreasing x by Time.deltaTime, there is a little chance it will equals with 0, you should check with x <= 0.
Also you should check for input in Update.
I would save the reference of the enemy in OnCollisionEnter2D, and clear that in OnCollisionExit, and handle the attack in the Update. Something like that:
private GameObject _enemy;
private float _actCooldown = 3.0f;
private void Update()
{
if (Input.GetKeyDown(KeyKode.Mouse0) && _actCooldown <= 0.0f)
{
if (_enemy != null)
{
Destroy(_enemy);
_enemy = null;
}
_actCooldown = 3.0f;
}
_actCooldown -= Time.deltaTime;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.name.Equals("Enemy")) _enemy = collision.gameObject;
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject == _enemy) _enemy = null;
}
Of course if there are more enemies, you'll have to add more logic to it.
i have a camera shake script but when i click start it directy goes off and it wont stop
in this script i wanted to trigger the shake effect
public class GameOver : MonoBehaviour
{
public Explosion shake;
void OnCollisionEnter2D (Collision2D coll)
{
Debug.Log("Collision!");
if (coll.gameObject.tag == "platform")
{
Destroy(gameObject);
shake.GameOver = true;
}
}
}
and this is the other script
public class Explosion : MonoBehaviour
{
public Transform cameraTransform;
private Vector3 orignalCameraPos;
public float shakeDuration;
public float shakeAmount;
private bool canShake = false;
public bool GameOver = false;
private float _shakeTimer;
void Start()
{
orignalCameraPos = cameraTransform.localPosition;
GameOver = false;
_shakeTimer = 0;
}
void Update()
{
if (GameOver = true)
{
ShakeCamera();
}
}
public void ShakeCamera()
{
_shakeTimer = shakeDuration;
StartCameraShakeEffect();
}
public void StartCameraShakeEffect()
{
if (_shakeTimer > 0)
{
cameraTransform.localPosition = orignalCameraPos + Random.insideUnitSphere * shakeAmount;
_shakeTimer -= Time.deltaTime;
}
else
{
_shakeTimer = 0f;
cameraTransform.position = orignalCameraPos;
GameOver = false;
}
}
}
if you are able to help me i would be very thankfull :)
in the statement if (GameOver = true) you are setting GameOver to true and then checking its value. I think you might have wanted to use if (GameOver == true) or if (GameOver) which will check if this variable is set to true.
I Am Working With Unity 3d and know little scripting and unity well. I Came To a point where I don't know what to do. My OnCollisionExit Don't Work on collision exit there is moment = true this dont work. Somebody told me you have not reset the variable. So I Don't Know How To Make It So Please Help. Thanks In Advance
This is The Player Script This Is My Script or code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Player : MonoBehaviour
{
public Animator anim;
public Transform housepos;
public Transform deadpos;
public static bool safe1_click = false;
public bool safe1_clicked = false;
public float speed = 25;
public Rigidbody rb;
Collider mycollider;
float Walk = 8;
float jump = 7;
float sadWalk = 6;
float idle = 0;
public static bool stopwalking = false;
public static bool Jump = false;
public static bool sadwalk = false;
public static bool freeze = false;
public static bool yourchance = false;
public static bool movement = true;
public bool movement23 = true;
// Start is called before the first frame update
void Start()
{
mycollider = transform.GetComponent<Collider>();
rb = GetComponent<Rigidbody>();
anim.SetFloat("Animation", Walk);
stopwalking = false;
Jump = false;
freeze = false;
}
// Update is called once per frame
void Update()
{
movement23 = movement;
if (movement == true)
{
safe1_click = safe1_clicked;
rb.velocity = new Vector3(speed * Time.deltaTime, rb.velocity.y, 0);
}
else
{
rb.velocity = new Vector3(0,0,0);
}
if (Jump == true)
{
anim.SetFloat("Animation", jump);
}
if (Jump == true)
{
anim.SetFloat("Animation", sadWalk);
}
if (stopwalking == true)
{
anim.SetFloat("Animation", idle);
}
}
public void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "stop")
{
Debug.Log("Stopped");
spawner.stopspawn = true;
movement = false;
return;
}
if (collision.gameObject.tag == "dec")
{
Debug.Log("oh");
freeze = true;
}
}
public void OnCollisionExit(Collision collision)
{
if (collision.gameObject.tag == "stop")
{
Debug.Log("Spawning");
spawner.stopspawn = false;
movement = true;
}
if (collision.gameObject.tag == "dec")
{
Debug.Log("oh");
freeze = false;
}
}
public void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag == "fre")
{
spawner.yourchance = true;
}
if (other.gameObject.tag == "Player")
{
Destroy(other.gameObject);
}
if (other.gameObject.tag == "dec")
{
freeze = true;
Debug.Log("oh");
}
if (other.gameObject.tag == "new")
{
yourchance = true;
Debug.Log("stopstop");
}
if (other.gameObject.tag == "con")
{
Debug.Log("collide happened");
movement = true;
}
}
private void OnTriggerExit(Collider other)
{
if(other.gameObject.tag == "dec")
{
freeze = false;
Debug.Log("oh");
}
}
}
I'm having trouble keeping this method running. It runs for 1 frame them shuts itself off. I am having trouble working out the logic to keep it running. Yes, the enemy does detect if the player is within a field of view, and it does stop when it collides with walls, it also stops detecting the player when they leave the fov.
I've tried changing around if statements, but it's overall very important that the code runs based on the player existing in the FOV collider. The problem is pretty specific, so I don't know what research to do.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(AudioSource))]
public class EnemyAI : MonoBehaviour
{
public float patrolSpeed, chaseSpeed, chaseWaitTime, patrolWaitTime, castRadius;
public Transform[] wayPoints, wayPOI;
public Transform player;
public Animation flinch, die;
public AudioClip grunt, callOut, death;
public LayerMask mask;
public PlayerCheck check;
private float chaseTimer, patrolTimer, wanderTimer;
private int destIndex, destInit, destStart, health;
private bool playerIn;
protected string aggro, resting, warned, sawPlayer;
protected bool patroling;
public bool aggress;
private NavMeshAgent agent;
private Transform playerLP;
private Vector3 startPos;
private Animator anim;
private AudioSource aud;
MeshCollider fieldOfView;
void Awake()
{
//patroling = true;
startPos = transform.position;
destInit = destIndex;
agent = GetComponent<NavMeshAgent>();
agent.autoRepath = true;
agent.autoBraking = true;
fieldOfView = transform.GetChild(0).GetComponent<MeshCollider>();
if (fieldOfView == null)
{
Debug.LogError("The first object MUST be FOV, otherwise the script will not work correctly. 1");
}
check = GameObject.FindObjectOfType<PlayerCheck>();
anim = GetComponent<Animator>();
}
void FixedUpdate()
{
if (check == null)
{
check = GameObject.FindObjectOfType<PlayerCheck>();
}
playerIn = check.playerIn;
RaycastHit hit;
if (Physics.Linecast(transform.position, player.position, out hit, ~mask))
{
if (!playerIn)
{
Debug.DrawLine(transform.position, hit.point, Color.red);
}
else if (hit.collider.gameObject != null)
{
if (!hit.collider.CompareTag("Player"))
{
Debug.DrawLine(transform.position, hit.point, Color.blue);
return;
}
else
{
Debug.DrawLine(transform.position, hit.point, Color.green);
aggress = true;
}
}
}
if (aggress)
{
Aggro(sawPlayer);
}
if (patroling)
{
GoToNext();
}
}
void GoToNext()
{
patroling = true;
aggress = false;
if (wayPoints.Length == 0)
return;
if (playerIn)
return;
if (agent.remainingDistance < .7f)
{
agent.SetDestination(wayPoints[destIndex].position);
destIndex = (destIndex + 1) % wayPoints.Length;
}
}
void Aggro(string condition)
{
if (condition == sawPlayer)
{
Chase(player);
}
}
void Chase(Transform transform)
{
patroling = false;
if (playerIn)
{
agent.SetDestination(transform.position);
print("Chasing");
}
else
{
**Wander(sawPlayer, 15);**
print("Wander, please");
}
}
**void Wander(string condition, float time)**
{
patroling = false;
print(time);
wanderTimer += Time.deltaTime;
print("Wandering");
//this is where I'm having the most trouble, it will print wandering for 1 //frame then stop and go back to patroling
//once the player leaves the fov. I'm trying to figure out where the method //stops and why.
if (condition == sawPlayer)
{
if (wanderTimer >= time)
{
wanderTimer = 0;
if (!agent.pathPending && agent.remainingDistance < .5f)
{
GoToNext();
}
}
else
{
Vector3 vec;
vec = new Vector3(Random.Range(agent.destination.x - 10, agent.destination.x), Random.Range(agent.destination.y - 10, agent.destination.y), Random.Range(agent.destination.z - 10, agent.destination.z));
agent.destination = transform.InverseTransformDirection(vec);
if (agent.remainingDistance < .3f || wanderTimer > time)
{
GoToNext();
}
}
}
}
}
I'm having trouble getting my for loop to work. I can either get it to work once, or without a limit. I'm trying to get coins to instantiate up to 3 times. I don't think the for loop itself is wrong, but the structure somewhere is. The loop is in the Looted function.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class corpseKicked : MonoBehaviour {
private Rigidbody2D rb;
private Animator anim;
public GameObject coinPrefab;
public Transform coinSpawn;
private bool kicked = false;
public float timer = 2f;
public GameObject deathFlamePrefab;
private bool flamer;
private bool pay = false;
private bool broke = false;
void Start ()
{
anim = GetComponent<Animator> ();
rb = GetComponent<Rigidbody2D> ();
}
// Update is called once per frame
void Update ()
{
Looted ();
}
public void OnTriggerEnter2D(Collider2D other)
{
if (!kicked && other.gameObject.tag == "kickIndicator") {
kicked = true;
transform.Translate (0.0f, .05f, 0.0f);
}
}
public void Looted ()
{
if (!pay && kicked) {
pay = true;
Instantiate (coinPrefab, coinSpawn.position, coinSpawn.rotation);
kicked = false;
pay = false;
for (int i = 1; i <= 3; i++)
Debug.Log ("$$$$$$$$$");
}
}
Try this instead:
public void Looted ()
{
if (!pay && kicked) {
pay = true;
Instantiate (coinPrefab, coinSpawn.position, coinSpawn.rotation);
kicked = false;
pay = false;
for (int i = 1; i <= 3; i++)
{
Debug.Log ("$$$$$$$$$");
}
}
}
See the difference in the for condition. Think of it as "do this loop as long as this condition is true." Since i starts at one and is incremented at the end of the statement i++, this will run three times as you expect.
It's more common and idiomatic though to say
for (int i = 0; i < 3, i++)
unless there's a special reason you need to count starting at 1.
public GameObject deathFlamePrefab;
private bool flamer;
private bool pay = false;
private bool broke = false;
private int kickedCount = 0;
void Start ()
{
anim = GetComponent<Animator> ();
rb = GetComponent<Rigidbody2D> ();
}
// Update is called once per frame
void Update ()
{
Looted ();
}
public void OnTriggerEnter2D(Collider2D other)
{
if (!kicked && other.gameObject.tag == "kickIndicator") {
kicked = true;
transform.Translate (0.0f, .05f, 0.0f);
}
}
public void Looted ()
{
if (!pay && kicked) {
pay = true;
kicked = false;
if (kickedCount < 3)
{
Instantiate (coinPrefab, coinSpawn.position, coinSpawn.rotation);
kickedCount++;
}
pay = false;
}
}
Am uncertain as to what pay does but you may need to place that within the if statement