- Home /
How To Properly Return An Object If Within Distance Range?
I have a method right now that will find the closest TreeInstance to something within a given distance range, and then return that TreeInstance. If there is not a single TreeInstance within the given distance range, I try to have the method return null.
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public static class TerrainExtensions {
/// <summary>
/// Finds the closest TreeInstance to the specified GameObject within "range"
/// </summary>
public static T FindClosestTreeInstanceTo<T>(this Terrain terrain, GameObject closestTo, float range)
{
TreeInstance closestTreeInstance = terrain.terrainData.treeInstances.OrderBy(treeInstance => Vector3.Distance(Vector3.Scale(treeInstance.position, terrain.terrainData.size) + terrain.transform.position, closestTo.transform.position)).First();
if (Vector3.Distance(Vector3.Scale(closestTreeInstance.position, terrain.terrainData.size) + terrain.transform.position, closestTo.transform.position) <= range)
{
return (T)Convert.ChangeType(closestTreeInstance, typeof(T));
}
else
{
return (T)Convert.ChangeType(null, typeof(T));
}
}
}
I believe it works as intended, however unity will throw the error "
I don't want anything returned if it's not in range (null), but I don't want Unity to throw these errors either. IS there a better way to do this, or a way to suppress errors on that method? Thanks!"InvalidCastException: Null object can not be converted to a value type."
Why do you need this method to be generic? It seems all you are returning are TreeInstance objects.
Can you please also post the code where you call the method?
Answer by VivienS · Jan 29, 2016 at 09:51 AM
Looks more like a C# issue than a Unity issue:
It seems the error occurs because you're calling the method with a type that is not nullable (a value type). If you really need this, you shouldn't return
(T)Convert.ChangeType(null, typeof(T));
but
default(T);
which will result in null if called with reference type and 0 if called with a value type. https://msdn.microsoft.com/en-us/library/xwth0h0d.aspx
However, do you really need this method to be generic? Why not just return TreeInstance
objects?
That was the first thing I did actually. I used to return a default TreeInstance, but then a TreeInstance at default position gets return that doesn't technically exist (Unity creates an empty game object that isn't the Terrain your working with. Also sometimes it is used to instantiate game objects and it was throwing even more errors when trying to do that.
As for making the method generic, It was required to Typecast the Generic Type to null, so that if no object in range exists (its null) it would actually return a null value of some sort, I guess a generic kind.
Do you know of a way to suppress the error in Unity, because it only appears during run time, and functions as it should?
I mean change the method declaration to public static TreeInstance FindClosestTreeInstanceTo(this Terrain terrain, GameObject closestTo, float range). Then you can just return the TreeInstance without typecasting it and in the other branch return null. If you just want to get rid of the error, use the above mentioned code return default(T); in the "null"-branch. This should not produce a default TreeInstance...?
Hah! No, my bad. TreeInstance is actually a struct not a class, so there is this a non-null default value. Well, you could try to use nullable types when calling on this method, no? https://msdn.microsoft.com/en-us/library/2cf62fcy.aspx
As for supressing error messages: Don't know about that, I'm afraid.
Your answer
Follow this Question
Related Questions
GameObject1 move away when GameObject2 gets close 1 Answer
Remove objects from list when they are out of range. 0 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers