I wrote mesh generator for MeshCollider. But sometimes, when I set convex property to ture, some errors happened to appear the log.
For example, now I have a Mesh with 44 vertices and this errors:
CreateTrianglesFromPolygons: convex hull has a polygon with less than 3 vertices!
or
convex hull init failed! Try to use the PxConvexFlag::eINFLATE_CONVEX flag.
or something else...
All I want, is to detect and handle this error. But try catch do not work:
try
{
collider.convex = true;
UnityEngine.Debug.Log("Success! TrCount: " + collider.sharedMesh.triangles.Length.ToString()); // "Success! TrCount: 84"
}
catch
{
UnityEngine.Debug.Log("Error occur"); // never appear
}
Maybe there are some rules to detect it before setting convex to true.
Thank you for any help ).
You forgot catch(ExceptionType)
try
{
collider.convex = true;
UnityEngine.Debug.Log("Success!");
}
catch(Exception e)
{
UnityEngine.Debug.Log("Error occur: " + e.Message);
}
Include using System; at the top.
EDIT:
The error message is NOT an exception so the method below should solve your problem. Remember that convex requires the triangle to be < 255 to work. The code below makes sure that your trigs is between 3 and 254.
if (generatedMesh.triangles.Length >= 3 && generatedMesh.triangles.Length < 255)
{
collider.convex = true;
UnityEngine.Debug.Log("Success!");
}else
{
UnityEngine.Debug.Log("Error occur: " + e.Message);
}
Related
I want to create a model in openSCAD
and then I want to cut optionally cut a hole into it (Using difference)
so I can do something like
module model_with_hole( hole=false) {
difference() {
//the_model()
if (hole) {
//the_hole()
}
}
}
But this is actually saying something like "always cut something out of the model except that what you cut might be nothing if a hole is not required".
another alternative would be:
module model_with_hole( hole=false) {
if (hole) {
difference() {
//the_model()
//the_hole()
}
}
else {
//the_model()
}
}
But this is actually saying something like "if you need a hole then render the model and remove the hole, otherwise just render the model".
Is there a way to code this such that the call to render the model would only exist once and the difference action would only happen if required?
if (hole) {the_hole()} the_model();
So the code would feel more like saying render the model and the if require cut the hole ?
Perhaps this is what you want:
add the parameters of the holes to a vector and use this vector in a for loop in difference(). If the vector is empty, nothing is subtracted from the model, try the four examples:
module model(l) {
cube(size = l, center = true);
}
module hole(pos, dim) {
translate(pos) cylinder(h = dim[0] + 0.1, r = dim[1], center = true);
}
// holes = [];
// holes = [[[0,0,0],[10, 1]]];
holes = [[[-2.5,-2.5,0],[10, 0.5]], [[0,0,0],[10, 1]], [[2.5,2.5,0],[10, 1.5]]];
// holes = [[[-2.5,-2.5,0],[10, 1]], [[-2.5,2.5,0],[10, 1]], [[2.5,2.5,0],[10, 1]], [[2.5,-2.5,0],[10, 1]], [[0,0,0],[10, 1]]];
difference() {
model(10);
for (h = holes) hole(h[0], h[1]);
}
I use Particle Playground 3.0.3 in Unity3d 5.4.1f1 on Windows 10 to make spline of particles. I need to add and remove node interactively. When I try do this through script — nodes add and remove but particles stop to move after 1-2 (rarely more) iterations.
The code is simple:
// ================================================
void Update()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
AddNewPoint();
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
RemoveLastPoint();
}
}
// ================================================
public void AddNewPoint()
{
Debug.Log("Add at " + spline.NodeCount);
spline.AddNode(spline.NodeCount);
}
// ================================================
public void RemoveLastPoint()
{
spline.RemoveLast();
Debug.Log("Removed, size is " + spline.NodeCount);
}
I also checked that the same problem happens when I add/remove nodes by Playground Spline component in Editor. But as I see there's no such problem when I make a long delay (about 5-10 seconds) between two additions or removals.
Does anyone knows what happens? Also, screenshots:
initial state, particles move http://take.ms/xUWBPH
after several nodes added particles die http://take.ms/Y7a16
Flip a 2d GameObject and place it on exact the same position works well on both sides.
Rotating 2d GameObject works well on both sides
However, if i flip the GameObject, by executing Cmd_DoTheSpawn, the rotation is not reflected on the "other" client.
I would need help to get this work.
Here is the code I use:
[Command]
void Cmd_DoTheSpawn(GameObject myGameObject) {
// Check if front or back?
char lastChar = myGameObject.tag[myGameObject.tag.Length - 1];
if (lastChar == 'B') {
convertedObjectTag = unet_Back2Front [myGameObject.tag];
} else {
convertedObjectTag = unet_Front2Back [myGameObject.tag];
}
GameObject my1 = Resources.Load (convertedObjectTag) as GameObject;
float z = myGameObject.transform.localEulerAngles.z;
//var go = (GameObject)Instantiate (my1, myGameObject.transform.position, myGameObject.transform.localRotation);
var go = (GameObject)Instantiate(my1, myGameObject.transform.position, Quaternion.Euler(0f, 0f, z));
go.name = go.name.Remove(go.name.Length - 7); // Remove the '(Clone)' in name
NetworkServer.SpawnWithClientAuthority(go, base.connectionToClient);
print ("myGameObject: " + myGameObject.transform.position);
if (myGameObject == null)
print ("myGameObject NULL" + myGameObject.transform.position);
Rpc_DoTheRot (go, myGameObject);
myNetID = myGameObject.GetComponent<NetworkIdentity> ();
Cmd_DestroyGameObject (myNetID.netId);
}
Thanks to #LumbusterTick i did get it to work, meaning the rotation is ok. However, i did get another problem that i do not fully understand.
I added the following code:
[ClientRpc]
public void Rpc_DoTheRot(GameObject newGO, GameObject oldGO) {
print ("Rpc_DoTheRot");
if (newGO == null)
print ("newGO NULL");
if (oldGO == null)
print ("oldGO NULL");
newGO.transform.rotation = oldGO.transform.rotation;
}
...which i call after spawn but prior to destroy, see updated code above.
It does place the flipped prefab in correct rotation but i do get the following messages:
oldGO NULL
as well as:
NullReferenceException: Object reference not set to an instance of an object
I know perfectly well what that means but not why it happen as all values of the myGameObject is nulled when i send them. ...and i do it prior to destroy.
I do not understand why it is null but still effect the rotation on the new object.
From you command function after you network spawn call a clientrpc function and pass instantiated gameobject to it and change its rotation there.
I'm currently working on a game that will randomly generate a dungeon for the player. This is made up of a whole heap of different methods being called from different files. I seem to have the code working to be able to calculate how much space is available on the other side of the door.
There is a catch however; the code only seems to work when I am outputting to the console using CCLOG. I wrote a good chunk of the code without testing and decided to then work through it in steps to see how the code worked (I figured I would just get it to run without bugs and next I will check my values).
After I had established that the code was successfully checking available space in each direction, while listing the locations it had checked, I decided that I would like to remove the CCLOG output. Unfortunately though, doing this caused the code to stop working.
//First check "forward"
bottom = CGPointMake(startLocation.x + forwardDirectionModifier.x, startLocation.y + forwardDirectionModifier.y);
top = bottom;
do
{
currentLocation = CGPointMake(top.x + forwardDirectionModifier.x, top.y + forwardDirectionModifier.y);
tileType = [tileCache getTileType:currentLocation];
if (tileType == TileTypeFiller)
{
top = currentLocation;
CCLOG(#"Top location is %#", NSStringFromCGPoint(top));
}
} while (tileType == TileTypeFiller || top.y != 63);
This is a small snippet from the code; It is the section of code I think is most likely the issue. Essentially the problem is that if I comment out or delete the line CCLOG(#"Top location is %#", NSStringFromCGPoint(top)); it will stop working.
Here are some more details:
I have several little chunks of code like this, as long as I CCLOG in each one, it will be able to move to the next. If i were to comment out any of them, it would stop progress to the next chunk.
I can change the CCLOG to output anything and it will still work, it just has to be there.
I have tried cleaning the project.
There are more CCLOG's that aren't used inside any loops and they can be removed without consequence.
Does anyone have a solution to this? As far as I can tell, whether I do or do not output something to the console,it shouldn't have an effect on whether or not the code will execute.
Thanks in advance.
EDIT: At Ben Trengrove's suggestion, I am adding in further examples of where the CCLOG is being used.
This code immediately follows the previously listed code.
//Check left relative to door
farLeft = CGPointMake(startLocation.x + leftDirectionModifier.x, startLocation.y + leftDirectionModifier.y);
do
{
currentLocation = CGPointMake(farLeft.x + leftDirectionModifier.x, farLeft.y + leftDirectionModifier.y);
tileType = [tileCache getTileType:currentLocation];
if (tileType == TileTypeFiller)
{
farLeft = currentLocation;
CCLOG(#"Far Left location is %#", NSStringFromCGPoint(farLeft));
}
} while (tileType == TileTypeFiller || farLeft.x !=0);
//Check forwards from far left
top2 = farLeft;
do
{
currentLocation = CGPointMake(top2.x + forwardDirectionModifier.x, top2.y + forwardDirectionModifier.y);
tileType = [tileCache getTileType:currentLocation];
if (tileType == TileTypeFiller)
{
top2 = currentLocation;
CCLOG(#"Top2 location is %#", NSStringFromCGPoint(top2));
}
} while ((tileType == TileTypeFiller)|| (top2.y != 63));
What does your tile cache return as a tileType when there is no tile at currentLocation ? TileTypeFiller by any chance ? if yes, you have an almost certain never ending loop there, under the right circumstances..
EDIT :
please add a line after the loop
CCLOG(#"");
and place a breakpoint on that line. See if the program stops there.
So the problem has now been solved, it seems that in part there was a fault in my logic.
Here is what I've done that now works:
do
{
currentLocation = CGPointMake(top.x + forwardDirectionModifier.x, top.y + forwardDirectionModifier.y);
tileType = [tileCache getTileType:currentLocation];
if (tileType == TileTypeFiller)
{
top = currentLocation;
}
locationCount++;
} while ((tileType == TileTypeFiller) && (locationCount != 15));
CCLOG(#"Top location is %#", NSStringFromCGPoint(top));
The change is that I've switched to AND as opposed to OR. I also changed the second part of the while as I realised that due to my max room size, I never needed to check more than 15 locations in any given direction.
Thanks a lot to everyone that has helped. I'm still not entirely sure though how the use of CCLOG was somehow able to help get past a fault in logic but at least it is working now.
I am trying to make a game in where you can stab an enemy, the enemy struggles for about a second and drops dead. (ragdoll);
i think its best to just show my script and you know what I mean:
In an on trigger enter script:
if(other.tag == "enemy"){
other.transform.parent.gameObject.name = ("enemy" + currentEnemy);
print(other.name);
gameObject.Find("enemy" + currentEnemy).GetComponent("RagdollOrNot").MakeKinematicFalse();
BloodParticle.emit = true;
Stabbed = true;
Character.GetComponent("MouseLook").enabled = false;
Character.GetComponent("CharacterMotor").enabled = false;
}
and in the update function:
if(Stabbed == true){
StopBleeding ++;
}
if(StopBleeding > 50){
Stabbed = false;
StopBleeding = 0;
currentEnemy ++;
Character.GetComponent("MouseLook").enabled = true;
Character.GetComponent("CharacterMotor").enabled = true;
BloodParticle.emit = false;
}
Now when my knife enters the collision of the enemy the enemy imediatly drops to the floor.
I tried putting the:
gameObject.Find("enemy" + currentEnemy).GetComponent("RagdollOrNot").MakeKinematicFalse();
in the update function in if(StopBleeding > 50).
if I do that I get an error of Null reverance exception becaus the script cand find the enemy. While it can I its in the trigger enter.
Basicly my question is: Is there any way to fix this error to give it a 50 frame delay (all the rest in StopBleeding works)?
Or is there any way I can put a simple delay in before the Ragdoll gets activated?
Thanks in advance
You can use StartCoroutine("DelayDeath"); where DelayDeath is the name of a method. See below.
if(other.tag == "enemy"){
other.transform.parent.gameObject.name = ("enemy" + currentEnemy);
print(other.name);
StartCoroutine("DelayDeath");
BloodParticle.emit = true;
Stabbed = true;
Character.GetComponent("MouseLook").enabled = false;
Character.GetComponent("CharacterMotor").enabled = false;
}
private IEnumerator DelayDeath()
{
//this will return...and one second later re-enter and finish the method
yield return new WaitForSeconds(1.0f);
gameObject.Find("enemy" + currentEnemy).GetComponent("RagdollOrNot").MakeKinematicFalse();
}
Since you're asking specifically about Unity JS and not C#, you'll use the yield keyword.
print("foo");
yield WaitForSeconds (5.0); // waits for 5 seconds before executing the rest of the code
print("bar");
On stabbing you could look up the enemy object but save it away in a variable instead of issuing the enemies dead. After the bleeding finishes you don't have to look up the enemy and can trigger the death on the saved one.
Another hint: Don't count frames as frames might be of different length. Add up time from Time.deltaTime until you reach let's say 2 seconds and then trigger the death.
Hope that helps.