Optimization issues with 2D sandbox terrain generation - c#

My game:
Each block has a class that doesn't run anything on update, and there is a 200 x 10 span of blocks. I'm implementing random terrain generation later, and this is what I want to be done.
BLOCK CODE: (in every single block, should I optimize? or do it differently?)
using UnityEngine;
using System.Collections;
public class scr_blockMechanics : MonoBehaviour {
//#EDITABLE VARS
public string block_blockType;
private SpriteRenderer spriteRenderer;
public bool isMineable { get; set; }
public bool isRandomlyGenerated { get; set; }
public bool isWall { get; set; }
//#STATIC VARS
GameObject obj_blockItem;
//#START
void Start () {
obj_blockItem = GameObject.Find("main_blockItem");
spriteRenderer = GetComponent<SpriteRenderer>();
if(isRandomlyGenerated == false){
isMineable = false;
}
//#CREATING WALLS
/*if(isRandomlyGenerated == true && isWall == false){
//#TODO Create walls!
GameObject obj_blockWall = (GameObject)Instantiate(gameObject, transform.localPosition, Quaternion.identity);
obj_blockWall.name = obj_blockWall.name + " WALL";
obj_blockWall.transform.localPosition = new Vector3(
obj_blockWall.transform.localPosition.x,
obj_blockWall.transform.localPosition.y,
5);
Collider2D obj_blockWall_collider = obj_blockWall.GetComponent<Collider2D>();
obj_blockWall_collider.enabled = false;
Color obj_blockWall_color = Color.grey;//new Vector4(64, 64, 64, 1);
SpriteRenderer spriteRenderer_wall = obj_blockWall.GetComponent<SpriteRenderer>();
spriteRenderer_wall.color = obj_blockWall_color;
scr_blockMechanics blockMechanics_wall = obj_blockWall.GetComponent<scr_blockMechanics>();
blockMechanics_wall.isRandomlyGenerated = true;
blockMechanics_wall.isMineable = false; //#TODO: not yet mineable, because it's a wall.
blockMechanics_wall.isWall = true;
obj_blockWall.name = blockMechanics_wall.block_blockType+" WALL";
}*/
}
//#CREATE ITEM
void createItem(int uid){
GameObject obj_blockItemNew = (GameObject)Instantiate(obj_blockItem, transform.localPosition, Quaternion.identity);
obj_blockItemNew.rigidbody2D.isKinematic = false;
obj_blockItemNew.name = gameObject.name + " ITEM";
}
//#DESTROY BLOCK
void destroyBlock(){
//print ("'"+transform.name+"' has been destroyed!");
//spriteRenderer.color = Color.red;
createItem(0);
Destroy(transform.gameObject);
}
//#UPDATE
void Update () {
if(renderer.IsVisibleFrom(Camera.main) == true){
renderer.enabled = true;//gameObject.SetActive(true);
}
if(renderer.IsVisibleFrom(Camera.main) == false){
renderer.enabled = false;
}
}
}
'RANDOM' TERRAIN GENERATION
using UnityEngine;
using System.Collections;
public class scr_randomGen : MonoBehaviour {
private SpriteRenderer spriteRenderer;
private string[] block_blockTypes = new string[]{
"DIRT", //#UID 0
"STONE", //#UID 1
"STONE_BRICK", //#UID 2
};
void GENERATE(){
//#DEFAULTS
GameObject obj_block = GameObject.Find("main_block");
int pos_startingPosX = -100;
int pos_endingPosX = 100;
int pos_startingPosY = 0;
int pos_endingPosY = 10;
float X = 0;
float Y = 0;
//#TERRAIN GENERATION
for(X=pos_startingPosX;X<pos_endingPosX;X=X+1){
GameObject obj_blockNew = (GameObject)Instantiate(obj_block, new Vector3(0 + (1*X),0,0), Quaternion.identity);
scr_blockMechanics blockMechanics = obj_blockNew.GetComponent<scr_blockMechanics>();
blockMechanics.isMineable = true;
blockMechanics.isRandomlyGenerated = true;
blockMechanics.block_blockType = block_blockTypes[2];
obj_blockNew.name = blockMechanics.block_blockType+" "+X+", "+Y;
for(Y=pos_startingPosY;Y<pos_endingPosY;Y=Y+1){
obj_blockNew = (GameObject)Instantiate(obj_block, new Vector3(X,1 + (1*Y),0), Quaternion.identity);
blockMechanics = obj_blockNew.GetComponent<scr_blockMechanics>();
blockMechanics.isMineable = true;
blockMechanics.isRandomlyGenerated = true;
blockMechanics.block_blockType = block_blockTypes[2];
obj_blockNew.name = blockMechanics.block_blockType+" "+X+", "+Y;
}
}
}
void Start () {
GENERATE();
}
void Update () {
}
}
I have it so that if the camera isn't looking at blocks it disables their sprite renderer so it's not rendering as much.
Should I just disable them as a whole? I get 6fps upon running the game.
When I only have, say, 10 - 20 blocks instead of 2000 I get 130 FPS (which is still low in my opinion)
What's the best way to optimize this? make it so I get atleast 70 fps? I wanted to use Java but I don't feel comfortable with the editor and I already put 2 hours of work into this.
I have looked at people's projects in Java and it's a lot smoother and they don't have to worry about the lag. And I have looked at peoples posts saying that it is possible to create a Terarria-like game in Unity but it's always going to be laggy.
Anybody got a good idea on how to fix the lag issues?

Related

How to grab the nearest object from a spherecast?

Im using a Grab Object script that grabs a object that is inside the trigger collider.
But when i try to grab a object with more than 1 object inside the collider it grabs all the objects at the same time (example image with two bricks grabbed at the same time).
I need a rule to grab only the nearest object.
two brick grabbed
im using this script to grab the objects.
Found it on a YT tutorial and tweaked it
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PickUp : MonoBehaviour {
public float throwForce = 100;
public bool canHold = true;
public GameObject item;
public GameObject tempParent;
public GameObject poof;
public GameObject vanish;
public GameObject poofParent;
public Transform guide;
public bool isHolding = false;
float distance;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
distance = Vector3.Distance(item.transform.position, guide.transform.position);
if (Input.GetKeyDown("space"))
if (distance <= 6f)
{
isHolding = true;
item.transform.position = tempParent.transform.position;
//Poof
GameObject myPoof = Instantiate(poof, Vector3.zero, Quaternion.identity) as GameObject;
myPoof.transform.parent = poofParent.transform;
myPoof.transform.position = poofParent.transform.position;
Destroy (myPoof, 2);
//Particles
GameObject myVanish = Instantiate(vanish, Vector3.zero, Quaternion.identity) as GameObject;
myVanish.transform.parent = tempParent.transform;
myVanish.transform.position = tempParent.transform.position;
Destroy (myVanish, 4);
}
if (isHolding==true)
{
item.GetComponent<Rigidbody>().useGravity = false;
item.GetComponent<Rigidbody>().detectCollisions = true;
item.GetComponent<Rigidbody>().isKinematic = false;
item.transform.parent = tempParent.transform;
item.transform.position = tempParent.transform.position;
if (Input.GetKeyUp("space"))
{
Debug.Log("Trying to throw");
item.GetComponent<Rigidbody>().AddForce(guide.transform.forward * throwForce);
isHolding = false;
}
}
else
{
item.GetComponent<Rigidbody>().useGravity = true;
item.GetComponent<Rigidbody>().isKinematic = false;
item.transform.parent = null;
}
}
}
There is a sphere cast implemented in Unity's physics system, however it exists for a different purpose. Instead you're looking for Physics.OverlapSphere
Assuming that your guide object should be the center of the sphere you can determine the closest object (closestSelectedObject) in a specified selection radius.
float radiusOfSphere;
float smallesDistance;
Transform closestSelectedObject;
/***/
void Update(){
if(Input.GetKeyDown("space")){
Collider[] hitColliders = Physics.OverlapSphere(guide.transform.position, radiusOfSphere);
if(hitColliders.length > 0){
smallesDistance = radiusOfSphere;
foreach(Collider obj in hitColliders){
float tempDistance = Vector3.Distance(obj.transform.position, guide.transform.position);
if(tempDistance <= smallesDistance){
smallesDistance = tempDistance;
closestSelectedObject = obj;
}
}
/*other stuff that your code does*/
}
}
}
my final functional (Update) code here
Cant make it without your help #derHugo, thank you!
void Update () {
Collider[] hitColliders = Physics.OverlapSphere(guide.transform.position, radiusOfSphere);
var closestSelectedObject = hitColliders.OrderBy(obj => (obj.transform.position - guide.transform.position). sqrMagnitude).FirstOrDefault();
GameObject grabbed = GameObject.Find("grabbedObject");
if (grabbed != null)
{
Debug.Log("existe");
if (Input.GetKeyDown(KeyCode.Space) && !spaceDisabled) {
spaceDisabled = true;
}
}
else
{
if (Input.GetKeyDown("space"))
{
// targetObject does not exist in the scene
Debug.Log("NAOexiste");
if (closestSelectedObject.tag.Contains("CanPickup"))
{
closestSelectedObject.transform.position = tempParent.transform.position;
closestSelectedObject.transform.parent = tempParent.transform;
closestSelectedObject.GetComponent<Rigidbody>().detectCollisions = false;
closestSelectedObject.GetComponent<Rigidbody>().isKinematic = true;
closestSelectedObject.GetComponent<Rigidbody>().useGravity = true;
originalName = closestSelectedObject.name;
closestSelectedObject.name = "grabbedObject";
//Poof
GameObject myPoof = Instantiate(poof, Vector3.zero, Quaternion.identity) as GameObject;
myPoof.transform.parent = poofParent.transform;
myPoof.transform.position = poofParent.transform.position;
Destroy (myPoof, 2);
//Particles
GameObject myVanish = Instantiate(vanish, Vector3.zero, Quaternion.identity) as GameObject;
myVanish.transform.parent = tempParent.transform;
myVanish.transform.position = tempParent.transform.position;
Destroy (myVanish, 4);
}
}
}
if (Input.GetKeyDown(KeyCode.Q))
{
Debug.Log("Q key was pressed.");
grabbed.transform.parent = null;
grabbed.GetComponent<Rigidbody>().detectCollisions = true;
grabbed.GetComponent<Rigidbody>().isKinematic = false;
grabbed.GetComponent<Rigidbody>().useGravity = true;
grabbed.GetComponent<Rigidbody>().AddForce(guide.transform.forward * throwForce);
Input.ResetInputAxes();
grabbed.name = originalName;
}
}

Set behaviours(script a) controlled by booleans(script b) based on Time.time (flocking system)

I am working on a flocking system in Unity and am new to c#. I am working with 2 scripts - 1 that manages the overall flock (FlockTest) and the other that manages particle behaviour (FlockParticleBehaviour). I have followed a tutorial which has public boolean values that control seeking behaviour in FlockParticleBehaviour through FlockTest. In play mode, I can toggle these booleans to change the goal seeking behaviour. However, I want to automate this toggling based on time (To add it to an AR session). I have added an if statement to void Update() in the FlockTest and when I hit play, the seekGoal and obedient boolean boxes switch on and off but nothing happens to the particles. I have tried using an invoke method which didn't work(no errors but boxes dont switch on and off) and thought about trying a coRoutine but I am not sure this will work since I don't want to stop and start my script. I am at a loss as to how to get the particles obeying the boolean in update. Am I meant to be referencing in my particle behaviour script's flock function? Very new so would love some help if anyone knows a better way forward!
FlockTest script (contains if statement)
using System.Collections.Generic;
using UnityEngine;
public class FlockTest : MonoBehaviour
{
public GameObject[] particles;
public GameObject particlePrefab;
public int particleCount = 10;
public Vector3 range = new Vector3(5,5,5);
public Vector3 innerLimit = new Vector3(1,1,1);
public bool seekGoal = true;
public bool obedient = true;
public bool willful = false;
[Range(0, 200)]
public int neighbourDistance =50;
[Range(0,2)]
public float maxForce = 0.5f;
[Range(0,5)]
public float maxvelocity = 2.0f;
// Start is called before the first frame update
void Start()
{
int time = (int)Time.time;
particles = new GameObject[particleCount];
for(int i = 0; i < particleCount; i++)
{
Vector3 particlePos = new Vector3(Random.Range(-range.x, range.x), Random.Range(-range.y, range.y), Random.Range(-range.z, range.z));
particles[i] = Instantiate(particlePrefab, this.transform.position + particlePos, Quaternion.identity) as GameObject;
particles[i].GetComponent<FlockParticleBehaviour>().manager = this.gameObject;
}
}
void Update()
// the toggles in the inspector are changing but nothing is happening with the particles.
{
int time = (int)Time.time;
if(time == 3f) {
seekGoal = false;
obedient = false;
willful = true;
}
if(time == 6f)
{
seekGoal = true;
obedient = true;
willful = false;
}
}
}
FlockParticleBehaviour script
using System.Collections.Generic;
using UnityEngine;
public class FlockParticleBehaviour : MonoBehaviour
{
public GameObject manager;
public Vector3 location = Vector3.zero;
public Vector3 velocity;
Vector3 goalPos = Vector3.zero;
Vector3 currentForce; //this is a current force position. pushes particle around by adding all the other forces
// Start is called before the first frame update
void Start()
{
velocity = new Vector3(Random.Range(0.01f, 0.1f), Random.Range(0.01f, 0.1f), Random.Range(0.01f, 0.1f));
location = new Vector3(this.gameObject.transform.position.x, this.gameObject.transform.position.y, this.gameObject.transform.position.z);
}
Vector3 seek(Vector3 target)
{
return(target - location);
}
void applyForce(Vector3 f)
{
Vector3 force = new Vector3(f.x, f.y, f.z);
if(force.magnitude > manager.GetComponent<FlockTest>().maxForce)
{
force = force.normalized;
force *= manager.GetComponent<FlockTest>().maxForce;
}
this.GetComponent<Rigidbody>().AddForce(force);
if(this.GetComponent<Rigidbody>().velocity.magnitude > manager.GetComponent<FlockTest>().maxvelocity)
{
this.GetComponent<Rigidbody>().velocity = this.GetComponent<Rigidbody>().velocity.normalized;
this.GetComponent<Rigidbody>().velocity *= manager.GetComponent<FlockTest>().maxvelocity;
}
Debug.DrawRay(this.transform.position, force, Color.white);
}
Vector3 align()
{
float neighbourdist = manager.GetComponent<FlockTest>().neighbourDistance;
Vector3 sum = Vector3.zero;
int count = 0;
foreach (GameObject other in manager.GetComponent<FlockTest>().particles)
{
if(other == this.gameObject) continue;
float d = Vector3.Distance(location, other.GetComponent<FlockParticleBehaviour>().location);
if (d < neighbourdist) {
sum += other.GetComponent<FlockParticleBehaviour>().velocity;
count++;
}
}
if (count >0)
{
sum /= count;
Vector3 steer = sum - velocity;
return steer;
}
return Vector3.zero;
}
Vector3 cohesion()
{
float neighbourdist = manager.GetComponent<FlockTest>().neighbourDistance;
Vector3 sum = Vector3.zero;
int count = 0;
foreach (GameObject other in manager.GetComponent<FlockTest>().particles)
{
if(other == this.gameObject) continue;
float d = Vector3.Distance(location, other.GetComponent<FlockParticleBehaviour>().location);
if(d < neighbourdist)
{
sum += other.GetComponent<FlockParticleBehaviour>().location;
count++;
}
}
if (count > 0)
{
sum /= count;
return seek(sum);
}
return Vector3.zero;
}
void flock()
{
location = this.transform.position;
velocity = this.GetComponent<Rigidbody>().velocity;
if(manager.GetComponent<FlockTest>().obedient && Random.Range(0,50) <=1)
{
Vector3 ali = align();
Vector3 coh = cohesion();
Vector3 gl;
if(manager.GetComponent<FlockTest>().seekGoal)
{
gl = seek(goalPos);
currentForce = gl + ali +coh;
}
else
currentForce = ali + coh;
currentForce = currentForce.normalized;
}
if(manager.GetComponent<FlockTest>().willful && Random.Range(0,50)<=1)
{
if(Random.Range(0,50)<1) //change direction
currentForce = new Vector3(Random.Range(0.01f, 0.1f), Random.Range(0.01f, 0.1f),Random.Range(0.01f, 0.1f));
}
applyForce(currentForce);
}
// Update is called once per frame
void Update()
{
flock();
goalPos = manager.transform.position;
}
}
Several points:
it is much easier and cleaner to set your flock manager directly as FlockTest, not GameObject to avoid GetComponent calls.
I cannot understand what you want to achieve by calling (int)Time.time and comparing it later with 3 and 6. Time.time returns the number of seconds that passed from the start of the application. So your code in Update method of FlockTest script will not have any chance to be called after the seventh second of your game passed. So obedient will always be true and willful will always be false after the seventh second.
Your Random.Range(0, 50) <= 1 is quite a low chance. It will return an int value from 0 to 49, so it is only a 2% chance that your changes in FlockTest will apply to FlockParticleBehaviour instance. Is it what you wanted to get? You can try to remove this random from the if statement to make this chance 100% and check if this is an issue.
Right now it seems like the chance of changing something is too low to see it in several seconds of the game. As I've said above, after the seventh second your bool values will never change.

How to get Panel to show when character lands on a specific position on game board after dice roll in Unity

I have a 3D board game in Unity. I would like to move my character without having to press a key, but most importantly I would like to show a dynamic panel in canvas for whatever square the character lands on. So far I have the dice rolling and the character moving (after pressing a key) the correct amount of squares, but I am unable to figure out how to activate the panel based on the square color. Any help would be appreciated.
Here is my CharacterScript:
public class CharacterScript : MonoBehaviour
{
public Path currentPath;
public int squarePosition;
public int squares;
bool isMoving;
public GameObject PinkSquarePanel = GameObject.FindGameObjectWithTag("PinkSquare");
public GameObject CyanSquarePanel = GameObject.FindGameObjectWithTag("CyanSquare");
public GameObject WhiteSquarePanel = GameObject.FindGameObjectWithTag("WhiteSquare");
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape) && !isMoving)
{
squares = DiceNumberTextScript.diceNumber;
}
StartCoroutine(Move());
if (squares == 0)
{
ActivateSquarePanel();
}
}
IEnumerator Move()
{
if (isMoving)
{
yield break;
}
isMoving = true;
while (squares > 0)
{
Vector3 nextPosition = currentPath.squareList[squarePosition + 1].position;
while (MoveToNextSquare(nextPosition))
{
yield return null;
}
yield return new WaitForSeconds(0.1f);
squares--;
squarePosition++;
}
isMoving = false;
}
bool MoveToNextSquare(Vector3 goal)
{
return goal != (transform.position = Vector3.MoveTowards(transform.position, goal, 4f * Time.deltaTime));
}
void ActivateSquarePanel()
{
if (squarePosition.Equals(PinkSquarePanel))
{
PinkSquarePanel.GetComponent<CanvasGroup>().alpha = 1;
}
else if (squarePosition.Equals(CyanSquarePanel))
{
CyanSquarePanel.GetComponent<CanvasGroup>().alpha = 1;
}
else if (squarePosition.Equals(WhiteSquarePanel))
{
WhiteSquarePanel.GetComponent<CanvasGroup>().alpha = 1;
}
}
}
And here is my PathScript:
public class Path : MonoBehaviour
{
Transform[] squareObjects;
public List<Transform> squareList = new List<Transform>();
GameObject[] PinkSquares = GameObject.FindGameObjectsWithTag("PinkSquare");
PinkSquare[] pinkList = new PinkSquare[1];
GameObject[] CyanSquares = GameObject.FindGameObjectsWithTag("CyanSquare");
CyanSquare[] cyanList = new CyanSquare[1];
GameObject[] WhiteSquares = GameObject.FindGameObjectsWithTag("WhiteSquare");
WhiteSquare[] whiteList = new WhiteSquare[1];
private void OnDrawGizmos()
{
Gizmos.color = Color.black;
FillSquares();
for (int i = 0; i < squareList.Count; i++)
{
Vector3 currentPosition = squareList[i].position;
if (i > 0)
{
Vector3 previousPosition = squareList[i - 1].position;
Gizmos.DrawLine(previousPosition, currentPosition);
if(currentPosition.Equals(PinkSquares))
{
pinkList[i] = new PinkSquare();
}
else if (currentPosition.Equals(CyanSquares))
{
cyanList[i] = new CyanSquare();
}
else if (currentPosition.Equals(WhiteSquares))
{
whiteList[i] = new WhiteSquare();
}
}
}
}
void FillSquares()
{
squareList.Clear();
squareObjects = GetComponentsInChildren<Transform>();
foreach (Transform square in squareObjects)
{
if (square != this.transform)
{
squareList.Add(square);
}
}
}
}
I believe your issue is in your comparisons, you are trying to use an Equals to compare your currentPosition which is a Vector3 type to a GameObject[] which is an array of gameObjects. As I mentioned in my comments, this comparison will always fail as an array of gameObjects can not be equal to a vector.
Instead of using these lines, try this line:
if(squareList[i].gameObject.tag.CompareTag("PinkSquare")
The full snippet of if else would look like
if(squareList[i].gameObject.tag.CompareTag("PinkSquare")
{
pinkList[i] = new PinkSquare();
}
else if(squareList[i].gameObject.tag.CompareTag("CyanSquare")
{
cyanList[i] = new CyanSquare();
}
else if(squareList[i].gameObject.tag.CompareTag("WhiteSquare")
{
whiteList[i] = new WhiteSquare();
}
Your CharacterScript is going to need to get the gameObject or Transform from the Path script as it is only keeping track of indexes. Your issue in this script is you are comparing an integer to a GameObject which would never be true. I would also recommend not using OnDrawGizmos() as it is an editor only script and should only be used to render editor debugging tools. The only reference to a Gizmo I see in the function is Gizmos.color = Color.black; which does nothing as you are not rendering a gizmo anywhere. I would move this code to a different function and call it from your CharacterScript. Have the return type be GameObject or Transform of the square you are on, so the CharacterSCript can check which color it lands on. Using an Integer nor Vector3 to compare to a GameObject[] will never work.
I am not sure if there are issues elsewhere in the code, but as this comparison would always fail, none of these statements would get broken into. What this means is your panels would never have the chance to get their alpha set nor get created.

In my Unity C# game a gameobject is supposed to get thrown but it does absolutely nothing - what's the problem?

I am currently working on an Unity project in C# and my rigidbody isn't moving but I don't get an error. It should get thrown forward and upward but it does nothing - what am I doing wrong here?
Or can it be that my code isn't the problem but I messed something up unn unity?
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public GameObject ThrowObject;
public Canvas StartMenuC, m_SettingsC, m_ShopC;
public Button m_Start, m_Settings, m_Shop, m_CloseShop;
public RawImage m_SettingsImage, m_RTXON, m_RTXOFF;
public Texture m_Texture, m_Texture2;
public Toggle m_RTX;
public Text MoneyText;
string m_ForceXString = string.Empty;
string m_ForceYString = string.Empty;
public Rigidbody rb;
public Transform Forward, Upward;
private Vector3 m_StartPos, m_StartForce;
private Vector3 m_NewForce;
float m_ForceX, m_ForceY;
private int Money = 100;
// Start is called before the first frame update
void Start()
{
// rb = GetComponent<Rigidbody>();
m_NewForce = new Vector3(-5.0f, 1.0f, 0.0f);
m_ForceX = 10;
m_ForceY = 10;
m_ForceXString = "0";
m_ForceYString = "0";
m_StartPos = transform.position;
m_StartForce = rb.transform.position;
m_NewForce = new Vector3(m_ForceX, m_ForceY, 0);
MoneyText = GetComponent<Text>();
m_CloseShop.onClick.AddListener(CloseShop);
m_Settings.onClick.AddListener(Settings);
m_Start.onClick.AddListener(StartGame);
m_Shop.onClick.AddListener(ShopOpen);
m_SettingsImage = GetComponent<RawImage>();
m_SettingsC.enabled = false;
m_ShopC.enabled = false;
m_RTX.onValueChanged.AddListener(delegate {
CheckToggleOn(m_RTX);
});
// PlayerPrefs.SetInt("Money", Money);
// MoneyText.text = "Money: " + Money.ToString() + " $";
}
// Update is called once per frame
void Update()
{
}
void Settings()
{
if (m_SettingsC.enabled == false)
{
m_SettingsC.enabled = true;
}
else
{
m_SettingsC.enabled = false;
}
}
void ShopOpen()
{
m_ShopC.enabled = true;
}
void CloseShop()
{
m_ShopC.enabled = false;
}
private void CheckToggleOn(Toggle change)
{
if (m_RTX.isOn)
{
m_RTXOFF.enabled = false;
m_RTXON.enabled = true;
}
else
{
m_RTXON.enabled = false;
m_RTXOFF.enabled = true;
}
}
private void StartGame()
{
m_SettingsC.enabled = false;
StartMenuC.enabled = false;
m_ShopC.enabled = false;
Instantiate(ThrowObject, new Vector3(0, 356, 26), Quaternion.identity);
Debug.Log("HelloWorld");
if (ThrowObject)
{
Debug.Log("Throw object = true");
rb.AddForce(m_NewForce, ForceMode.Impulse);
}
}
}
What is my error?
And bc of: "It looks like your post is mostly code; please add some more details." and I don't know what else I am supposed to write here I'll tell what the game should look like when done it will be a 3D Mobile Game where you have the objective to throw stuff out of the window I know it's idiotic but its based on a true story from my old school where someone often threw schoolbags out of the window and had to get them back and the school was in the 5. floor
So I guess you want to add force to your newly instantiated "ThrowObject", correct?
However, instead of referencing this object, you add force to "rb", which seemingly is not at all connected to the new object.
Instead, you might want to do something like this:
rb = Instantiate(ThrowObject, new Vector3(0, 356, 26), Quaternion.identity).GetComponent<Rigidbody>();

When I die, a heart doesn't get removed, but no errors

I'm creating a 2d runner and i have this "collision.cs" file that I have my heart system in, I don't get any errors but when I die a heart doesn't get removed so what am I doing wrong?
The system is based on tags so I tried changing the tag system a lot but nothing worked; then I tried to change the way I find the gameobject after a while I saw that it was creating a lot off gameobjects instead of 3 so I tried to change the tag system around that but even that didn't work and I really don't want to have a plain text that says 3 lives etc.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Collision : MonoBehaviour {
public int lifes = 3 ;
//public GameObject Life_icon1;
//public GameObject Life_icon2;
//public GameObject Life_icon3;
public Sprite Heart;
public int current_icon = 3;
public GameObject ParentPanel;
public static int Coins = 0;
public float offset = 150f;
List<int> i = new List<int>() { 1 };
public int tagN;
void Update() {
tagN = i.Max() + 1;
}
// Use this for initialization
void Start () {
for(int x = 0; x < lifes; x++)
{
i.Add(x);
GameObject NewObj = new GameObject(); //Create the GameObject
Image NewImage = NewObj.AddComponent<Image>(); //Add the Image Component script
NewImage.gameObject.tag = x.ToString();
if(x == 0) {
NewImage.transform.position = new Vector3(0 + 40f, 0 + 40f , 0);
} else {
NewImage.transform.position = new Vector3(0 + offset, 0 + 40f , 0);
offset += 130f;
}
//print(x);
NewImage.sprite = Heart; //Set the Sprite of the Image Component on the new GameObject
NewObj.GetComponent<RectTransform>().SetParent(ParentPanel.transform); //Assign the newly created Image GameObject as a Child of the Parent Panel.
NewObj.SetActive(true); //Activate the GameObject
}
}
void AddLife(int amount) {
lifes++;
i.Add(amount);
GameObject NewObj = new GameObject(); //Create the GameObject
NewObj.gameObject.tag = tagN.ToString();
Image NewImage = NewObj.AddComponent<Image>(); //Add the Image Component script
NewImage.transform.position = new Vector3(0 + offset, 0 + 40f , 0);
NewImage.sprite = Heart; //Set the Sprite of the Image Component on the new GameObject
NewObj.GetComponent<RectTransform>().SetParent(ParentPanel.transform); //Assign the newly created Image GameObject as a Child of the Parent Panel.
NewObj.SetActive(true); //Activate the GameObject
}
void DelLife(int amount) {
Vector3 pos = transform.position;
offset -= 130f;
pos.x = -0.49f;
pos.y = -0.49f;
transform.position = pos;
i.RemoveAt(i.Max());
GameObject go = null;
if (GameObject.FindWithTag(tagN.ToString()) != null)
{
go = GameObject.FindWithTag(tagN.ToString());
}
if (go != null)
{
go.gameObject.SetActive(false);
}
}
void OnTriggerEnter2D(Collider2D other)
{
//extra life item collision
if(other.gameObject.name == "Heart_item") {
AddLife(1);
Destroy(other.gameObject);
}
if(other.gameObject.name == "Spike") {
DelLife(1);
}
if(other.gameObject.name == "Coin") {
Destroy(other.gameObject);
Coins += 1;
}
}
}

Categories

Resources