Is it possible to remove a part of a name given to a GameObject? For instance:
Im instantiating gameobjects for the use of bullets. I give them the name of the player shooting the bullet. So if a player's name is "Ben", his bullets are called Ben's bullet.
gameObject.name = playerName + "'s bullet";
Now I'm trying to use this name to know wich person gives the finishing blow to an other player. And to do this I want find the player object with the same name as the bullet, and update his kill count. So I want to remove the "'s bullet" part from the bullets name.
So long story short: Is it possible to remove a part of a name given to a GameObject?
Hope that this is clear enough en help is really appreciated. Thanks in advance!
Edit: This is the part where the name has to change:
if(other.gameObject.tag == "bullet"){
var colBullet = other.transform.name;
playerHealth = playerHealth - 5;
if(playerHealth <= 0){
onDie();
//colBullet = colBullet - "'s bullet";
GameObject.Find(colBullet);
} }
The name of the collided object is put in the colBullet variable. I printed it and it says: Playername's bullet. This works but now the only thing it needs is the 's bullet being removed
int suffixLength = "'s bullet".Length;
string player = gameObject.name.Substring(0, gameObject.name.Length - suffixLength);
But maybe it would be better to have a property that doesn't need manipulating to find the player name?
Long story short: keep a reference to the player in your GameObject, instead of its name. This way you save on look ups for the player if you want to, for example, increase the experience or gold the shooter has for each kill. For stray bullets, or recycled ones, just set Player to null.
Related
I am on Roblox again, and I wanna make a script where when a part is touched, if the player name is lorenzoomh, set the brickcolor to green. But if not, set it to red. my current code:
script.Parent.Touched:Connect(function(igottouched)
if game.Players.LocalPlayer.Name == "lorenzoomh" then
script.Parent.BrickColor = BrickColor.Green()
else
script.Parent.BrickColor = BrickColor.Red()
end
end)
which doesnt work btw
The answer to your question, "can I use a player's name in an if-statement" is yes. Your problem is that the LocalPlayer doesn't exist where you're trying to use it from.
See the docs for Players.LocalPlayer :
This property is only defined for LocalScripts ... as they run on the client. For the server (on which Script objects run their code), this property is nil.
You need to access the Player object a different way. The Touched event on a Part gives you access to the other object that touched it. You can use that to check if the other part belongs to a player's character model.
local target = game.Workspace.Part
-- listen for a player touching a block
target.Touched:Connect( function(otherPart)
-- check that the thing that touched is a character model
local character = otherPart.Parent
local isCharacter = character:FindFirstChild("Humanoid") ~= null
if isCharacter then
-- the character model name is usually the name of the player so use that
if character.Name == "lorenzoomh" then
target.BrickColor = BrickColor.Green()
else
target.BrickColor = BrickColor.Red()
end
end
end)
The Players service has a method for correlating a character model with a Player object specifically if a simple name check is not sufficient for your use case.
I have a game where a contact with the enemy ends the game but when I use removeFromParent on the enemy node it only removes the most recent one. The enemies are spawned using a switch statement to determine what side they enter from and once a contact happens and the game ends the nodes still present mess up the game by causing more contacts. If the user doesn't press anything and the enemies finish their trajectory during the game over screen then the problem doesn't occur.
Could I kill all the nodes from the screen any way once the game ends? Could I suspend input for like 3 seconds during the end screen to let the actions finish? Do I need to enumerate the enemies as they spawn to kill them off one by one once the game ends?
I've been stuck on this for like 3 days and would love some help. I think I explained it fairly well but if I need to show any code please ask and I will. I'm very new to swift by the way.
In your scene class you can write
// For all children
self.removeAllChildren()
// Removing Specific Children
for child in self.children {
//Determine Details
If child.name == "bob" {
child.removeFromParent
}
}
You can use the SKNode's method removeAllChildren(). Call it in the enemies' parent node. If it's the scene, the call should be scene.removeAllChildren().
Enumerating is probably the best way. I would give all your enemies a name(s)
let enemyName = "Enemy" // make it a property to avoid typos
myEnemySprite.name = enemyName
and than if you want to delete a particular set of enemies you can enumerate the scene and remove them
enumerateChildNodesWithName(enemyName) { (node, _) in
node.removeFromParent()
}
Note: If your enemies are children of another node (e.g enemyNode) instead of the scene you will have to enumerate like this
enemyNode.enumerateChildNodesWithName(enemyName) { (node, _) in
node.removeFromParent()
}
Alternatively you could also put all your enemies into an array after you added them to the scene.
Create the array
var enemiesArray = [SKSpriteNode]()
and than for each enemy you add to the scene you add them to the array as well
addChild(yourEnemy1Sprite)
enemiesArray.append(yourEnemy1Sprite)
Now if you want to delete them you can do this
for enemy in enemiesArray {
enemy.removeFromParent()
// clear array as well if needed
}
Hope this helps
Does anybody know how can I include scripts when my objects clone. In my game, I need to make that when my ball hit moving wall, then there is need to show new wall including my moving scripts. MY CASE: new wall is shown, but it is not moving.
Please help.
Kind regards
Well it is very easy.
First case: if you are using the prefab to instantiate, be sure to assign on the prefab your scripts.
Second case: if you are taking the template to instantiate directly from GameObject of wall, it should create the GameObject with exatly same scripts.
If it is still not moving, check in Inspector the cloned wall, if the scripts are enabled, and double check how the scripts work (maybe needs some initializing or whatever)
If your script is not on your prefab (for any reason), you can add via a script:
void CreateWall(){
GameObject obj = (GameObject)Instantiate(wallPrefab);
NewScript ns = obj.AddComponent<NewScript>();
}
The only advantage I could think about that way is that you can add specific components based on a specific situation. Say you want to add Script A if condition A or Script B if condition B:
void CreateWall(){
GameObject obj = (GameObject)Instantiate(wallPrefab);
switch(condition){
case A:
obj.AddComponent<ScriptA>();
break;
case B:
obj.AddComponent<ScriptB>();
break;
}
}
I'm having a big problem here. I need to know which animator state I'm currently in, in order to make something happen. I've been searching a lot on this matter but because the mecanim animation is so new there isn't much info about it. At least not for unityscript.
Hope someone can help,
Thanks,
RĂ³bert Dan
Unfortunately I don't know JS, but the following C# lines should be easy to be translated.
Animator.GetCurrentAnimatorStateInfo returns an AnimatorStateInfo struct that describes the current animator state.
int stateId = Animator.StringToHash("Base Layer.State Name");
Animator anim = GetComponent<Animator>();
AnimatorStateInfo currentBaseState = anim.GetCurrentAnimatorStateInfo(0);
if (currentBaseState.nameHash == stateId )
{
//you are in stateId
}
Like you see in the example above the animator state's name are hashed (for performance reasons) so you have to hash the name of the state using Animator.StringToHash in order to retrieve the integer id associated with that particular state.
IT'S DO NOT WORK
Try this:
print (currentBaseState.nameHash +" "+ stateId);
And play the animation. They are different
NOVA, I realize your answer was 2 years ago but it matches if you use the "full path" instead of .nameHash.
obl.GetCurrentAnimatorStateInfo (0).fullPathHash == Animator.StringToHash ("Base Layer.StateName")
I am building a game where the player runs on a path. When the player triggers a collider, 2 enemy objects will spawn.
What I want is when the first collider trigger has been entered, I want the second collider, which is at a certain distance from the first collider, to get disabled for a certain time. How to achieve this?
If you'd like to disable the colliders so they won't hit or rebound off the wall, for example, then you can change your collider's "isTrigger" variable to true, to change it into a trigger volume instead of a solid collider. This has the effect of disabling it - in that it won't cause other objects to stop or rebound if they hit it.
For example:
function Update() {
if (Input.GetKeyDown(KeyCode.X)) {
collider.isTrigger = true;
}
}
Note that things like MouseOver still work.
If you want to disable that completely, you can try collider.enabled = false. I'm not sure if that works or not. If it doesn't, you can always scale down your collider:
var myOldSize:Vector3;
function DisableBoxCollider(myCollider:BoxCollider)
{
//actually just resizes it
myOldSize=myCollider.size;
myCollider.size=Vector3(0,0,0);
}
function EnableBoxCollider(myCollider:BoxCollider)
{
if(myOldSize!=Vector3(0,0,0))
myCollider.size=myOldSize;
}
You can use the above code to integrate it in your own project. I'm not going to spill out all of the code for you because else we'd miss the point of learning to program and post on Stackoverflow in general. But it should help you to get on your way. Try and play some with the code, and if you have questions, get back here and ask them, providing the question with some code to show what you have tried.