This is my script and I tried to make "" in case it's not one of the cases:
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "Platform")
Debug.Log("Touching Platform");
else Debug.Log("");
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.name == "OnTop Detector")
{
Debug.Log("On Top of Platform");
GameObject findGo = GameObject.Find("ThirdPersonController");
GameObject findGo1 = GameObject.Find("Elevator");
findGo.transform.parent = findGo1.transform;
}
else Debug.Log("");
}
But this "" not working. It's not deleting the text from the console while the game is running. And also when i stop the game and running it again it keep showing the last text of the Debug.Log.
I want to clear it if none of the If's happen in my script.
I saw this answer:
Answer
But i'm not sure if this is what I need and how to use it. Make a new script ?
And also what about errors. If I clear the Log in the console it will delete also erorrs if there will be some ?
In this screenshot it's in state after I touched the platform and then moved away from it but the text still exist in the console log:
The Debug.ClearDeveloperConsole() function is used when you clear logs from an application that was built while Debug Build is enabled in your project. There is no official API for clearing the Editor log.
Most Editor functionality can be replicated with Reflection just like hiding Gizmos and toggling the Stats Panel. I was going to write one but found this one.
This should clear every log on the Console tab.
using System.Reflection;
public void ClearLog()
{
var assembly = Assembly.GetAssembly(typeof(UnityEditor.ActiveEditorTracker));
var type = assembly.GetType("UnityEditorInternal.LogEntries");
var method = type.GetMethod("Clear");
method.Invoke(new object(), null);
}
Now, you can call ClearLog(); in your else statements.
EDIT:
This has changed recently in about ~Unity 2017. Since it is done with reflection, I consider it to change again anytime if any class, variable or function used in this code is renamed by Unity. Below is the new way to do this:
public void ClearLog()
{
var assembly = Assembly.GetAssembly(typeof(UnityEditor.Editor));
var type = assembly.GetType("UnityEditor.LogEntries");
var method = type.GetMethod("Clear");
method.Invoke(new object(), null);
}
Note that the Debug Log is longer than just one line (you can see it by clicking on said line).
You can try to use Debug.ClearDeveloperConsole() and see what you get.
Related
Hi I'm upgrade my unity game project from UNITY4.7.2 to UNITY2019.1.7f1 everything WORK ON UNITY EDITOR(UNITY2019.1.7f1) but after I'm build project to iPhoneX game isn't work for some function eg.FindGameObjectWithTag, GetComponent I'm check in code and found getcomponent is not work at calling time
I'm already solved this by add spawnArea prefab to inspector and call them but for another function that use GetComponent still not work.
please anybody suggest me about problem whem we call getcomponent problem.
I'm looking around my code, unity console and search in google too, and assume FindGameObjectWithTag, GetComponent and another code kind like those 2 have problem when upgrade unity4 to unity2019:
spawnPoint = GameObject.FindGameObjectWithTag(TagManager.spawnArea).transform;
if (currentVehicle != null) {
if(bigTruck)
DestroyImmediate(currentVehicle.transform.parent.gameObject);
else
DestroyImmediate(currentVehicle.gameObject);
}
GameObject vehicle = Instantiate(vehiclePrefabs[GameManager.instance.selectedCar], spawnPoint.position, spawnPoint.rotation) as GameObject;
currentVehicle = vehicle.GetComponent<BaseVehicle>();
if (currentVehicle == null) {
currentVehicle = vehicle.GetComponentInChildren<BaseVehicle>();
bigTruck = true;
} else {
bigTruck = false;
}
playerCamera.target = currentVehicle.transform;
playerCamera.vehicleFront = currentVehicle.transform.Find("Front");
In unity console when I use debug build they show "NullReferenceException: Object reference not set to an instance of an object." but I'm look around my code and not found any object that null reference, I test by compare with null eg.
if (currentVehicle == null) {
Debug.Log("currentVehicle is null");
}
Recently took an online course on beginner c# w/ unity and unfortunately the instructor ended the course with a broken and unfinished code. Having about 3 weeks of experience under my belt, I decided to learn, research, and make a viable build before moving on.
I've got two lists and a variable:
private List<Widget> WidgetList = new List<Widget>();
private List<Collider2D> ItemList = new List<Collider2D>();
private Collider2D itemSpot;
I then have an if statement inside the update method that, upon clicking the left mouse button the code changes the tag of the item clicked, adds that item to a ItemList, and generates a new Widget in that location.
if (Input.GetMouseButtonDown (0)) {
Vector2 worldPoint = Camera.main.ScreenToWorldPoint (Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast (worldPoint, Vector2.zero);
if (hit.collider.tag == "BlankItem") {
itemSpot = hit.collider;
itemSpot.tag = "FullItem";
RegisterItemSpot (itemSpot);
MakeWidget (hit);
}
}
This currently works fine, albeit I get the impression it was not the most ideal code (was not a well made course). The call to the RegisterItemSpot and MakeWidget methods work flawlessly, each properly uses the .Add to their respective lists. At the end of the game, I've got a method that also clears both lists without a problem.
Here is my hurdle: If I destroy a single instance of a Widget, I would like the itemSpot that was associated with it to change its tag to "BlankItem" again. I used a similar function to the previous to destroy the Widget:
void Update (){
if (Input.GetMouseButtonDown (0)) {
Vector2 worldPointt = Camera.main.ScreenToWorldPoint (Input.mousePosition);
RaycastHit2D hitt = Physics2D.Raycast (worldPointt, Vector2.zero);
if (hitt.collider.tag == "Tower" && destroyMode != false)
Destroy(hitt.transform.gameObject);
}
}
From there in the OnDestroy of the Widget class i have it remove itself from the list, and that works fine too.
In my head I imagine a couple lines of code that, within the OnDestroy of the Widget, would rename the itemSpot that was initially associated with that specific destroyed Widget. I don't know how to associate the new Widget with the specific itemSpot. Something along the lines of "if this object is destroyed, then the object associated with THAT collider gets retagged". The few ideas I have would require rebuilding this code from the ground up (maybe making arrays instead of lists?)and I feel like my novice brain would be better served just moving on to my next course instead of taking all that time. Maybe not? I just need some advice from more experienced folks. If i need to provide more information, please let me know (10 classes of hundreds of code seemed like too much to just throw on here).
EDIT: Ive included the MakeWidget() method and the RegisterItemSpot() and RegisterWidget() methods. I should have from the get-go, very sorry!
public void MakeWidget (RaycastHit2D hit){
if (!EventSystem.current.IsPointerOverGameObject) {
Tower newWidget = Instantiate (widgetBtnPressed.WidgetObject);
newWidget.transform.position = hit.transform.position;
RegisterWidget (newWidget);
widgetBtnPressed = null;}
}
public void RegisterItemSpot (Collider2D itemSpot){
ItemList.Add(itemSpot);
}
public void RegisterWidget (Widget widget)
{
WidgetList.Add(widget);
}
I think your best approach is creating a new containerclass, and then declaring a new list of said class. Here is an example
public class WidgetContainer()
{
public Widget widget;
public Collider2D collider;
}
Then replace your two lists with this one
public List<WidgetContainer> widgetContainers = new List<WidgetContainer>();
Then merge your makewidget and registeritemspot method into one method and create and add a new WidgetContainer to the list. Now you will always have a connection stored between these two variables.
var newContainer = new WidgetContainer
{
widget = newWidget,
collider = itemSpot
}
Finally in your OnDestroy() of the said widget as you describe, you can do this:
widgetContainers.First(x => x == this).collider.tag = "your tag here";
"this" references to instance of the class. In your case this would be your Widgetscript.
Do not that you will need to add this using statement at the top of your script for Linq.
using System.Linq;
Just need a way to get around this problem. I know what the issue is, I just need a viable solution.
So basically I have a script called MouseManager, which detects if you're looking at a specific game object and if you press "f" it tells another script, called UIManager, to open the GameObject's panel (I have a game where you can press f on a console and it enables a UI with a puzzle).
Basically, I want the user to be able to press "f" or "esc" and have it exit the panel, however if you press "f", it disables the panel but instantly re-enables it as you're still looking at the gameobject, and both checks are in Update()
I need a workaround, if anyone knows one PLEASE comment as this issue is getting on my nerves :P
Thanks
EDIT: By console I mean there's a GameObject that looks like a console.
EDIT 2: Here's the code, I'll put some comments in it so you can understand what each thing does. I will be refactoring it soon because it's messy...
void Start()
{
uiPuzzles = GameObject.Find("PuzzlesUI").GetComponentInChildren<UIManager>(); // Currently I have the UIManager set to a canvas called PuzzlesUI. I will soon be moving it to an empty GameObject.
}
void Update()
{
if (!uiPuzzles.invActive && !uiPuzzles.puzzleActive) // invActive and puzzleActive are two public booleans that just show if the inventory or any puzzle panel is empty (UIManager handles opening and closing the inventory too)
{
if (Input.GetButtonDown("Use") && !uiPuzzles.invActive && !uiPuzzles.puzzleActive) // Use key is bound to "f". Currently Im just checking if puzzleActive and invActive are still false.
{
ray = GetComponentInChildren<Camera>().ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 7)) // Raycast where you're looking
{
uiPuzzles.openPuzzleOverlay(hit.collider.name); // function in UIManager which will check if the hit collider is in a list of all the puzzle colliders currently added and if it is, open that panel.
}
}
}
}
As for UIManager:
public void openPuzzleOverlay(string collider) // Get a panel name
{
foreach (Puzzle item in puzzleList)
{
item.panelGameObject.SetActive(false); // Disable all puzzle panels.
if (item.consoleGameObject.name == collider) // unless its the given panel,
{
item.panelGameObject.SetActive(true); // then enable it.
Cursor.lockState = CursorLockMode.None; // Unlock the mouse.
Cursor.visible = true; // Show the mouse.
DisablePlayerUI(); // Disable the UI (e.g. crosshair)
puzzleActive = true; // Disable movement. (Because player movement requires puzzleActive and invActive to also be false
}
}
}
void Update ()
{
if (Input.GetButtonDown("Use") && puzzleActive && !invActive && // If you want to use a console and the puzzle is already active
!puzzleList.Where(p => p.panelGameObject.activeSelf).FirstOrDefault().panelGameObject.GetComponentInChildren<InputField>().isFocused) // Check if the currently active panel's input field is not focused.
{
ClosePuzzleOverlay(); // Close the puzzle.
EnablePlayerUI(); // Enable the UI.
}
}
public void ClosePuzzleOverlay()
{
foreach (Puzzle item in puzzleList)
item.panelGameObject.SetActive(false);
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
puzzleActive = false;
}
The problem is being caused by the two input checks. When F is pressed both are true so the UI is being closed and then opened in the same frame.
Take the Input code out of UIManager and keep it in one place. Then you can rework your input class to be something like this:
//MouseManager Update
if(Input.GetButtonDown("Use")){
if(uiPuzzles.isActive)
uiPuzzles.Hide();
else
uiPuzzles.Show(GetPuzzleName());
}
Now it will only call either open or close on the frame which F is pressed down.
I am trying to get the scene to switch when a method in the script TrippleBall returns 0. I know it returns 0 at the appropriate time because I have tested it. Here is my code to switch scenes:
void OnTriggerEnter(Collider col)
{
if (col.gameObject.tag == "ball")
{
col.gameObject.GetComponent<Ball>().setIsOffScreen(true);
/*error*/ if (GameObject.Find("TrippleBalls").GetComponent<TripleBall>().getBallCount() == 0) {
Debug.Log("Loading next screen...");
SceneManager.LoadScene("GameOverScene");
}
}
}
Here is an image to show where TrippleBalls is
The script TrippleBall is in the component TrippleBalls
Here is an image to show where the code above is located.
The code above is in a class called SceneTrigger which has been put in LBackBoard and RBackBoard
When I test the code, and the getBallCount returns 0 (to satisfy the condition above) I get the following error:
Object reference not set to an instance of an object
This error line sends me to where i marked error in the code above.
If anyone can help me figure this out, that would be awesome. Thank you!
You GameObject is named TrippleBall in the Scene but you are looking for TrippleBalls in the Scene. Simply change GameObject.Find("TrippleBalls") to GameObject.Find("TrippleBall");.
Also Don't use GameObject.Find in the OnTrigger function. It will slow down your game.Cach TripleBall in a local variable then you can re-use it.
TripleBall myTripleBall = null;
void Strt(){
//Cache TripleBall
myTripleBall = GameObject.Find("TrippleBalls").GetComponent<TripleBall>()
}
Now you can re-use it any time.
void OnTriggerEnter(Collider col)
{
if (col.gameObject.tag == "ball")
{
Debug.Log("COUNT IS: "+myTripleBall.getBallCount());
col.gameObject.GetComponent<Ball>().setIsOffScreen(true);
if (myTripleBall.getBallCount() == 0) {
Debug.Log("Loading next screen...");
SceneManager.LoadScene("GameOverScene");
}
}
}
Make sure to Add the GameOverScene scene in your Build Setting.
Advice:
Advice for you is that when Looking for another GameObject inside another GameObject, Use '/' like you would in a folder path. For example, TrippleBall is under Specialties GameObject. So use GameObject.Find("Specialties/TrippleBall"); instead of GameObject.Find("TrippleBall");
I'm having some discrepancy between playing my unity project inside the editor, and playing the build it makes.
Inside the editor, when I play my game I have code that spawns enemies when my player hits a target spot, which works. The enemies spawn and do what they need to do. However, when I build the project and run it, my player hits the same spot, but nothing appears.
I ran the project in the development mode and it claims I have not set the reference which I thought I had. I mean, if it didn't work, why is it working in the editor?
To try and combat this, I re-imported the assets I'm using. I remade the enemy spawn points. But I still get the same issue.
Has anyone ever came across this before?
If so, how can I fix this issue when it works inside the editor, but not in the build?
Here is my spawning function:
public GameObject SpawnEnemies()
{
Vector3 _position = new Vector3(transform.position.x, transform.position.y, transform.position.z);
// instantiate particel system
// Instantiate(_particle, _position, Quaternion.identity);
audio.PlayOneShot(_appearSound);
_clone = (GameObject)Instantiate(_enemy, _position, transform.rotation);
_ai = _clone.GetComponent<HV_BaseAI>();
_ai._waypoints = _wayPoints;
return _clone;
}
This is controlled by my section class which has the following function:
public List<GameObject> SpawnGroundEnemies()
{
List<GameObject> groundObjectList = new List<GameObject>();
for (int i = 0; i < _spawnPoints.Count; i++)
{
groundObjectList.Add(_spawnPoints[i].SpawnEnemies());
}
return groundObjectList;
}
Which, in turn is controlled by my section controller:
GameObject g, f;
g = GameObject.FindGameObjectWithTag("SectionController");
f = GameObject.FindGameObjectWithTag("SectionController");
HV_SectionController tempSectionControllerGroundEnemies, tempSectionControllerFlyingEnemies;
tempSectionControllerGroundEnemies = g.GetComponent<HV_SectionController>();
tempSectionControllerFlyingEnemies = f.GetComponent<HV_SectionController>();
_groundEnemiesRemaining = tempSectionControllerGroundEnemies._numberOfGroundEnemies.Count;
_flyingEnemiesRemaining = tempSectionControllerFlyingEnemies._numberOfFlyingEnemies.Count;
_enemiesRemaining = _groundEnemiesRemaining + _flyingEnemiesRemaining;
if (!_moving)
{
if (_enemiesRemaining == 0)
{
MoveToNextSection();
}
}
if (_moving)
{
if (Vector3.SqrMagnitude(_camera.transform.position - _camNavMesh.destination) < 5.0f)
{
_moving = false;
// spawn the next set of enemies
// need this for each section of the game
// without this, no enemies will spawn
if (CurrentSection == 1)
{
_numberOfGroundEnemies = _sections[0].SpawnGroundEnemies();
_enemiesRemaining = _numberOfGroundEnemies.Count;
}
if (CurrentSection == 2)
{
_numberOfFlyingEnemies = _sections[1].SpawnFlyingEnemies();
_enemiesRemaining = _numberOfFlyingEnemies.Count;
}
if (CurrentSection == 3)
{
_numberOfGroundEnemies = _sections[2].SpawnGroundEnemies();
_enemiesRemaining = _numberOfGroundEnemies.Count;
}
}
}
}
private void MoveToNextSection()
{
if (_currentSection == _sections.Count)
{
_currentSection = 0;
}
_camNavMesh.SetDestination(_sections[_currentSection]._cameraTransform.position);
_lookAtPoint.SetTimer(_sections[_currentSection]._cameraLookAtTarget.position);
_moving = true;
_currentSection += 1;
}
Can anyone see anything i'm doing wrong?
Update
Since this post, I've tried reimporting all of my assets again. I've even created a fresh project and done a fresh build that way, but I still have the same issue. Also, to help, I've take two screen grabs to show what I mean.
First off, the game running in the unity editor:
As you can see, there is 4 skeletons on the bridge. These guys appear when I hit play in the unity editor.
Now, when I build the project, this is same sections:
As you can see, no enemies, but when its a development build, it says I've no reference set. In the output log unity genereates, it gives me this message:
NullReferenceException: Object reference not set to an instance of an
object at HV_SpawnGroundEnemy.SpawnEnemies () [0x00052] in
C:\Users\sean.obrien\Desktop\Medieval Darkride
Level\Assets_scripts\Enemy Scripts\HV_SpawnGroundEnemy.cs:37
at HV_Section.SpawnGroundEnemies () [0x0000d] in
C:\Users\sean.obrien\Desktop\Medieval Darkride
Level\Assets_scripts\Helper Scripts\HV_Section.cs:26
at HV_SectionController.Update () [0x000c2] in
C:\Users\sean.obrien\Desktop\Medieval Darkride
Level\Assets_scripts\Helper Scripts\HV_SectionController.cs:72
Again, this only appears in the built version of the game. When I run this inside Unity, everything works fine. I honestly have no idea why this issue arises when it works fine in the editor but not in the build.
There's most probably two cases here. Either you've not saved your scene yet, or you're not including the correct scene while making the build.
If it's the first case, just save the scene. If it's second, then you need to choose proper scene in the build settings and then rebuild.
Explanation:
You might have saved the scene as some other file, but the build setting does not update the scene file dynamically. It'll still point to the old scene. So you just need to remove the old scene and add the current scene you're using.