unity Destroy instantiated GameObject - unity3d

i want to destroy a game object that i instantiated and i get a lot of errors when i try to do so like "the name clone does not exist in the current context" , "cannot convert object expression to type UnityEngine.Object". i tried a lot of things i found online but nothing helps. here is my code :
if(distance<renderDistance)
{
if(!temp)
{
GameObject clone = Instantiate(chunk,transform.position,transform.rotation)as GameObject;
temp = true;
}
}
else
{
Destroy(clone);
}

You were getting "the name clone does not exist in the current context" error because you declared this variable ('clone') inside "if(!temp)" brackets and it hasn't existed after closing bracket.
Try this code:
GameObject clone = null;
if (distance < renderDistance)
{
if(!temp)
{
clone = (GameObject)Instantiate(chunk, transform.position, transform.rotation);
//be sure 'chunk' is GameObject type
temp = true;
}
}
else
{
if (clone != null)
Destroy(clone);
}
Let me know if you have any questions or need more help.

Related

unity network variabe occasional writing permission error

I am new to unity netcode and I am trying to implement a grabbing/dropping mechanism for a 3rd person game.
But my network variable occasionally throws a confusing error out at the host side when client side "drop" something:
[Netcode] Client wrote to NetworkVariable`1 without permission. No more variables can be read. This is critical. => NetworkObjectId: 5 - GetNetworkBehaviourOrderIndex(): 1 - VariableIndex: 0
Sometimes it throws 1 of this error, sometimes it throws 2 and in rare case it doesn't throw error at all.
What is the possible reason for this?
Basically my approach is:
(below using clientNetworkTransform)
Grab:
calling grabServerRpc( callerClientId ) in the Grabbable object by the local player
passing the ownership of the Grabbable setting the network variable grabbedClientId to callerClientId in grabServerRpc()
in the OnValueChange delegate for every player, check if LocalPlayerId == grabbedClientId
if equal, set the local targetTransform to the grabbing point of the player and serval more properties to complete the grab
(the OnValueChange also check if grabbedClientId == Default value before doing anything to prevent execution due to dropServerRpc())
Drop:
unset the properties to drop it.
call the dropServerRpc() in the Grabbable
removeOwnership() in the dropServerRpc()
restore the grabbedClientId to default value to complete the drop
public void grab(ulong grabbedClientId){
this.grabServerRpc(grabbedClientId);
}
[ServerRpc(RequireOwnership = false)]
private void grabServerRpc(ulong grabClientId){
if (this.grabbedClientId != TPNetworkGrabbable.GRABBED_CLIENT_DEFAULT) return;
this.networkObject.ChangeOwnership(grabClientId);
this.grabbedClientId = grabClientId;
print("grabbed");
return;
}
private void OnGrab(ulong previous, ulong current){ // OnValueChange for grabbedClientId
if (this.grabbedClientId == TPNetworkGrabbable.GRABBED_CLIENT_DEFAULT) return; // prevent calling due to changes in drop()
if (this.grabbedClientId != NetworkManager.LocalClientId) return;
TPNetworkGrabbingControl grabbingControl = NetworkManager.LocalClient.PlayerObject.GetComponent<TPNetworkGrabbingControl>();
this._targetTransform = grabbingControl.grabPosition;
this.rigidbody.useGravity = false;
this.transform.rotation = Quaternion.Euler(0, 0, 0);
this.rigidbody.freezeRotation = true;
}
public void drop(){
if (this.grabbedClientId != NetworkManager.LocalClientId) return;
if (this.grabbedClientId == TPNetworkGrabbable.GRABBED_CLIENT_DEFAULT) return;
this._targetTransform = null;
this.rigidbody.useGravity = true;
this.rigidbody.freezeRotation = false;
this.dropServerRpc();
}
[ServerRpc(RequireOwnership = false)]
private void dropServerRpc(){
this.networkObject.RemoveOwnership();
this.grabbedClientId = TPNetworkGrabbable.GRABBED_CLIENT_DEFAULT;
print("dropped");
}
what I have done:
global searched my project and every single modification to any network variable are already done in [ServerRpc] and they are server write authoritive by default.
Googled and found basically nothing related to this specific error, except this:
though the solution seems to not apply to my case and the example does not exist anymore.

Load all existent files (sprites) from Application.persistentDataPath? Unity

In my game, you can take screenshots of the world, which are saved in Application.persistentDataPath. I want to make a gallery where you can then see all these screenshots. Because you need to write to the file, I can't use Resources folder or Application.streamingAssetsPath. I could read the files one sprite at a time, using the name, but that's not really practical. So how could I load all files and add them to an array or list? I basically need the equivalent of Resources.LoadAll(). Does anyone know how to achieve this?
You can use Directory.GetFiles(string,string) to return all filepaths in the persistentData folder e.g. by file extension ("*.jpg")
Then you can use e.g. UnityWebRequestTexture.GetTexture also on local file paths and load assets from the persistent data path like
public Dictionary<string, Texture2D> textures = new Dictionary<string, Texture2D>();
private void Start()
{
var fileNames = Directory.GetFiles(Application.persistentDataPath, "*.jpg");
foreach(var fileName in fileNames)
{
StartCoroutine (LoadFile(fileName));
}
}
private IEnumerator LoadFile(string filePath)
{
using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(filePath))
{
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.Log(uwr.error);
}
else
{
// Get downloaded asset bundle
var texture = DownloadHandlerTexture.GetContent(uwr);
// Something with the texture e.g.
// store it to later access it by fileName
var fileName = Path.GetFileName(filePath);
textures[fileName] = texture;
}
}
}

Unity NullReferenceException after accessing a variable of another script

after trying to acces a variable in another Script of another GameObject out of a List, I get every time an Exception. The Main code looks like this:
private var BombList = new List.<GameObject>();
private var BombTemp : GameObject;
private var BombTempScript : Bomb;
function Start () {
BombTemp = null;
BombTempScript = null;
BombList.Clear();
}
function Update () {
if(BombList.Count > 0){
for(var i : int = 0; i<BombList.Count;i++){
BombTemp = BombList[i];
BombTempScript = BombTemp.GetComponent.<Bomb>();
if(BombTempScript.bombCountdown <= 0){
BombTempScript.explode();
BombList.Remove(BombTemp);
addHealth(-1);
}
}
}
}
function OnTriggerEnter (other : Collider) {
if(other.gameObject.CompareTag("Bomb")){
BombList.Add(other.gameObject);
other.gameObject.GetComponent.<Bomb>().notListed = false;
}
}
function OnTriggerExit(other : Collider){
if(other.gameObject.CompareTag("Bomb")){
if(BombList.Contains(other.gameObject)){
BombList.Remove(other.gameObject);
other.gameObject.GetComponent.<Bomb>().notListed = true;
}
}
}
If there isn't an object in the List the Code in the Update function does not work as intended. But when there is an object inside it produces a NullReferenceException in the if Line:
if(BombTempScript.bombCountdown <= 0)
The variable which is pointed at named bombCountdown, is continuously changing.
Here is the intended code:
#pragma strict
public var bombCountdown : float;
public var notListed : System.Boolean;
function Start () {
bombCountdown = 10.0;
notListed = true;
}
function Update () {
bombCountdown -= Time.deltaTime;
if(bombCountdown <= 0 && notListed)
explode();
}
function explode(){
Destroy(myText);
Destroy(this.gameObject);
}
I hope you could help us.
Thanks in advance, the Silly Scientists
I think there's a small bug in the code, which is making it happen.
In the Bomb script, in the following portion, you are destroying the bomb object, without removing it from the BombList of the first script.
As a result, BombList[i] may become null, as it may already have been destroyed.
If you make sure that you update the BombList when the Bomb is destroyed, I guess the code will work.
You remove gameobject from list in the for loop, so all indexes in the list shift to left from removed object. And the count is not the same as for loop started. At first you must complete your for loop, then remove objects after that.

Unity3D: Automatic target according to price

I've been working on a simulator in Unity3D and i need a customer object to be able to automatically find the shop object with the lowest price.
I've done a little testing on this myself and found it to be rather difficult to achive. So i was hoping someone could help me tweak my code a bit further in the right direction? :)
Here's the code i've got so far:
var cityName : String;
var shopScript : MarketScript;
function FindShopPlace () : GameObject //Make a queueing system
{
var max : float;
var target : GameObject;
var gos : GameObject[];
var goScript : MarketScript;
gos = GameObject.FindGameObjectsWithTag("market");
for (var go : GameObject in gos)
{
goScript = go.GetComponent(MarketScript);
if (goScript.cityName == cityName)
{
if (goScript.resalePrice >= max && goScript.cityName == cityName)
{
max = goScript.resalePrice;
}
if (goScript.resalePrice < max && goScript.cityName == cityName)
{
print ("test");
target = go;
}
}
}
shopScript = target.GetComponent(MarketScript);
return target;
}
Currently with this code, the target is never found and assigned. I get the following NullReferenceException from line number 3 from the bottom:
NullReferenceException: Object reference not set to an instance of an
object ConsumerScript.FindShopPlace () (at
Assets/_MyAssets/_Scripts/ConsumerScript.js:268) ConsumerScript.Update
() (at Assets/_MyAssets/_Scripts/ConsumerScript.js:96)
You get a NullReferenceException because target was never set to any object.
What you are doing in your loop is (1) finding the maximum price and (2) finding the last Object after maximum that is smaller than the maximum.
So if your prices in order are 1, 2, 3 target will never be set because in each step you are setting the maximum to the new value and are never setting target. Even when set its not necessarily the cheapest. Consider the prices 1, 3, 2.
First Step: Set maximum to 1
Second Step: Set maximum to 3
Third Step: Set target to the GameObject with price 2
If you get errors like this try out simple examples like this to get to the bottom of things. Also you are using the variable maximum(comparing the first time) without ever setting it to anything, not sure if this works in Javascript(it might) but its bad practice
What you really want isnt finding the maximum price or minimum price but the GameObject with the lowest resalePrice.
var min : float;
var success : boolean;
var firstHit : boolean;
...
success = false;
firstHit = true;
for (var go : GameObject in gos)
{
goScript = go.GetComponent(MarketScript);
if (goScript.cityName == cityName)
{
success = true;
if(firstHit) // alternatively to this would be to set minimum to a value that is higher than every possible price ( thats also what i meant with you shouldnt use max without setting it to anything)
{
min = goScript.resalePrice;
target = go;
}
else
{
if (goScript.resalePrice < min )
{
min = goScript.resalePrice;
target = go;
}
}
}
}
if(success)
{
shopScript = target.GetComponent(MarketScript);
return target;
}
else
{
// TODO: handle the case that there isnt a shop in the city.
// Maybe give an error Message with Debug.Log if this isnt supposed to happen
return null;
}

CommandBars.FindControl throwing an exception

I am trying to use the FindControl Method of the CommandBars object in a VSTO Word addin to get what else a command bar object
Code is as follows
private void WireContextMenu(string MenuID,string Tag, string ID, ref Office.CommandBarButton Control)
{
try
{
object missing = System.Type.Missing;
Control = (Office.CommandBarButton)this.Application.CommandBars[MenuID].FindControl((object)Office.MsoControlType.msoControlButton, ID, Tag, missing, missing);
if (Control == null)
{
Control = (Office.CommandBarButton)this.Application.CommandBars[MenuID].Controls.Add(Office.MsoControlType.msoControlButton, ID, missing, missing, missing);
Control.Caption = "Biolit Markup Selection";
Control.Tag = Tag;
}
Control.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.cb_Click);
}
catch (Exception Ex)
{
}
}
The FindControl method is throwing a Type Mismatch Exception (-2147352571)
Any ideas
is this the right way anyhow to add a item to the right click menu of word and then make sure you dont add it if it already exists
Thanks
you are using Missing where Missing is not allowed as parameter
ref: link text
http://msdn.microsoft.com/en-us/library/system.type.missing.aspx
use code like this:
object type = MsoControlType.msoControlPopup;
object id = 1;
object tag = null;
object visible = 1;
object recusive = false;
//object missing = System.Type.Missing;
CommandBarControl barControl = popParent.FindControl(type, id, tag, visible, recusive);