I am new to Unity and scripting. I have two players and both are using a character controller. I have done this thing
I have used onControllerColliderHit function.
I have print the name like this gameobj.name.
It will show the name of the object that it hit
But the problem is it passes through it. I want that it's not able to pass through it and it will behave just like rigid bodies have. Like there must be effect of force through which second player hit it.
Check the doc. CharacterController as is has no RigidBody attached:
The Character Controller is mainly used for third-person or
first-person player control that does not make use of Rigidbody
physics.
Basically CharacterController is only a Collisor designed for preventing compenetration between the character and objects in the scene, but doesn't work as you expect when the collision occurs between 2 CharacterControllers.
Particularly:
The Controller does not react to forces on its own and it does not
automatically push Rigidbodies away.
Like shown in OnControllerColliderHit documentation you can manually handle the collision when this occurs. For example you can push away from each other the character controller object when they collide since you have the move direction:
Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
transform.Translate (-pushDir * offset);
Related
I am working on a car multiplayer game and i want if the player 1 and player2 is in circle and the other players (player 3,4,5) are outside the circle then the outside players (player 3,4,5) destroy and the circle players (player 1,2) won.. I dont understand hows it possible
I use ontrigger but i dont understand how can I apply this
Well with the limited knowledge of your project, the best advice I can give is have a collider for that circle, make it a trigger, and make a Collision script for it where you have the following method
void OnTriggerEnter (Collider other)
{
if (other.gameObject.name(or tag) == "Whatever the tag or name you want")
{
// check here for some field or identifier for the specific instance
// of the object to see which player entered the circle
carMasterScript.DestroyEverythingExcept(other);
}
}
Once you replace the vague things here with what you have in your scripts, and possibly make some Master script so you can have a single instance that can reach and access every car/player instance, this should trigger when another trigger object(make the cars trigger rigidbodies or kinematic bodies as well) and check to see if the thing that collided is a car, then protects that instance of the car while destroying every other one
Now I am facing a ghost object.
There was a script attached to an object which I deleted. But for some reason, the script's update function is always being called.
I added this line to the Update: Debug.Log(name), and its name is Flamestrike, but when I search it in the hierarchy, there are no results.
And if I set its position to 0,1,0 (so it should be visible), it is not visible in the game either.
So please help me because it drives me crazy :(
Edit:
Debug.Log("a");
if(transform.parent == null) {
transform.SetParent(GameObject.Find("Canvas").transform);
Debug.Log("Canvas");
}
I also tried this, and it prints Canvas, so it sets its parent to Canvas, but I can't see any Flamestrike objects under Canvas.
When Instantiating a prefab GameObject, for some reason it was being created with Hidden Flags. In order to solve this, we added the code: this.gameObject.hideFlag = HideFlags.None; which allowed the object to show up in the hiearchy finally.
The only other source I could find on this was this answer, which had basically no explanation as to why it occured. http://answers.unity3d.com/questions/921819/instantiated-prefabs-not-showing-up-in-hierarchy.html (quoted below)
Found the issue, not sure why but: These two ways are working (prefab
is a GameObject defined elsewhere).
Player1 = Instantiate(prefab) as GameObject;
Instantiate(prefab) as GameObject;
For some reason the prototype:
Instantiate(prefabName, position, rotation);
Was not working.
(Sorry if this is not the correct way to write this, but the comments are too short, and can't be formatted)
This not fully true, I think.
This hidden gameObject wasn't created via script. I dragged the prefab to the scene, then somehow I didn't delete the prefab fully. (or didn't even delete, just made it hidden)
It disappeared in the hieararchy, but it wasn't deleted fully.
After we made the object visible via script, now it is visible.
(but only in play mode, so I can't delete it, because it is not visible in scene view)
And it got some interesting components/attributes.
The original story:
FlameStrike - a Container for scaling purposes (empty gameObject)
-FlameStrike - a gameobject with animation, FlameStrike.cs script etc.
--Particle System - a part. system with this exact name.
But after we found the remaining hidden object it was like this:
So I don't understand what I did. It deleted some parts of the prefab, but also mixed some parts,
(like adding the Particle System object's Particle System component to this FlameStrike object)
then made it hidden. Is there a hotkey for this? :D Because it is not script related issue, I did this in the editor.
My question sums up what I'm trying to do.
I searched the internet and everyone keeps giving me the usual transform.Translate answer which doesn't work for me because I need the physics and collisions not just move the character forward.
I know how to do this with a rigidbody but my character keeps rolling, something I don't want.
If you character rolls, you could freeze some rotation constraints on the rigidbody.
Anyway here's something from the scripting reference for character controllers: https://docs.unity3d.com/Documentation/ScriptReference/CharacterController.Move.html
From it, I guess you can adjust for what you need.
Use a CharacterController and use its Move and SimpleMove functions. See the default character package to learn more about it, and, you could use the character motor script from that package as well.
Well First Add The Character Controller component create a new script called Move then open it and copy and paste this code
#pragma strict
function Update () {
var Controller : CharacterController = GetComponent(CharacterController);
var forward : Vector3 = transform.TransformDirection(Vector3.forward);
Controller.SimpleMove(forward);
}
After that add the script to your player object then you are done:)
I am making a platformer in Unity using unityscript.
I have a Player parent object with a character controller and various child objects. I have a similar enemy with a box collider. I'm struggling to differentiate between the collision happening when the player walks into the enemy and when the the player jumps and collides with it from above.
I've tried tagging the child objects but they don't have colliders. If I add colliders to the child objects, it messes up my character movement. I've also tried to test the position of the player:
if(col.transform.position.y >= transform.position.y){ killThyself(); }
But this doesn't work either - should I add the height of the enemy? If so how do I do that?
Any suggestions happily received.
Mmmm, I would use a boolean variable. Make it true when you press the jump button, and false once the jump has finished (when the player touches the floor). Declare the boolean as a public variable.
After that, in the OnCollision method, check the variable value.
I recommend you to read this to understand how to do that:
http://docs.unity3d.com/Documentation/ScriptReference/index.Accessing_Other_Game_Objects.html
Well, in your case I would assign the "otherScript" (the player script) doing this in the enemy control script:
var player : GameObject;
var playerScript: PlayerScript;
//I'm assuming "PlayerScript" is the name of the control script of your player,
//where you defined the "jump" variable.
function Start()
{
player = GameObject.FindGameObjectWithTag("Player");
//You also can use GameObject.Find("PlayerName")
playerScript = player.GetComponent(PlayerScript);
//Get the script from the player
}
function OnCollisionEnter(col : Collision)
{
if (playerScript.jump == true)
{
killThyself();
}
}
I'm finding the player on the function Start, to find it only ONCE, in the level load. Now, I assign the player script into a variable, so, when the player hit the enemy, this enemy will check if the player is jumping using his script. Remember to declare this variable as a public variable or this won't work.
Please comment if you have any problem using this method =)
I would use a second collider at the upper part of the enemy let's called it headCollider. Set isTrigger = true and maybe use a special physics material. If this headCollider is the first one to get triggered you know that the player chararacter is jumping on the enemy or is falling on it from above.
In OnTriggerEnter (Collider other) you can prepare some status variables (and maybe a timer for resetting the status). Also the current jump status like in V_Programmer's answer suggested should be useful for evaluation.
As Unity does not allow you to attach 2 colliders of the same kind, you have to use box and sphere or create an empty child and use that one.
I'm making a turn-based battle game in Unity3D and I have 2 scenes (a town scene and a battle scene). Whenever the character meets a monster, the game jumps to the battle scene where the character does battle and go back to the town scene after defeating or losing.
The problem is how to return to the town scene with the same state as when the character enters the battle scene (character position, statuses, etc.)
if I use
Application.LoadLevel('battlescene');
then
Application.loadLevel('townScene');
then the townscene will start from the first time. How to make the townscene continue from where we left off?
There are two ways that I think you can accomplish this. It all depends on your target platform and how important resources are but here we go:
1) If resources aren't an issue
You could put all your normal scene and battle scene objects in one scene.
Create two empty game objects (One for Town Scene objects and the other for Battle Scene Objects). You can then either have two versions
of your game character(s) or one. Then write a script that simply
switches the camera(s) from the town scene to the battle scene when
a battle is triggered and back to the town scene when the battle is
over.
If you have one version of each character you could simply add a script that changes the behaviour of your game character controller
to/from battle mode and normal/town mode.
If you have two versions of each character then you would simply need to write the appropriate character controller scripts and
activate/deactivate the game characters according to which one you are
using. This is how games like Final Fantasy 7,8,9 achieved the same
effect. There were two versions of the game characters: one for battle mode and the other for normal mode.
2) If resources ARE an issue
(and I think a more efficient way)
You could use the Application.LoadLevelAdditive function. This function allows you to load a different scene and rather than destroy everything in the current scene, it takes the new scene and all it's objects and adds them to the current scene.
So basically you can use it something like this:
Create a separate battlescene and within your scene, create an empty game object to hold every object in your scene.
In your noraml scene do the same.
When you need to go to battle mode use:
Application.LoadLevelAdditive ('battlescene');
And when/if you want to unload your battlescene after that you can do so by simply writing code to destroy the battlescene game object
since it contains everything from your battle scene.
As with the first method you can decide whether you want to have two different versions of your characters or not. One of the pros of having two versions is that if you want to save time by not going into detail with you game models (especially if your game is really big) you can have save processing power by using scaled down models for the town scene and using polished more detailed models for the battle scene, assuming your battle scene is a small stage representing the place where your characters are fighting. Think final fantasy VII. Just something to consider.
I hope that helps. I've written it all in a rush but lemme know if anything needs clearing up.
You can do it by script in c#
void onYourFunction()
{
Time.timeScale = 0; //pauses the current scene
Application.LoadLevelAdditive("YourNextScene"); //loads your desired other scene
}
And when you want to activate your game back you can use Time.timeScale = 1;
I know this is an old post, but there is one more method that can be used. This would be to save the state of the scene. This comes in handy when you don't expect users to have the resources for loading 2 scenes with the Application.LoadLevelAdditive. That method potentially can use twice the resources.
When you save the state (save all information that can change to a file or DB) you can then load the level at a later time and not have it sitting in memory. You could also use this to save your game.
I know it is on old post. But I have found another, very easy solution for my case. Just deactivating all GameObjects from one scene while the other is active and then reactivate it, as soon I go back to the root scene:
[Button]
public void UnPauseScene()
{
EndlessSceneCamera.gameObject.SetActive(true);
Time.timeScale = 1;
levelStatus = LevelStatus.Running;
foreach (var go in activeGameObjectsBeforeScenePaused)
{
go.SetActive(true);
}
}
[Button]
public void PauseScene()
{
//EndlessSceneCamera.gameObject.SetActive(false);
levelStatus = LevelStatus.Pause;
Time.timeScale = 0;
var allGameObjects = FindObjectsOfType<GameObject>().ToList();
activeGameObjectsBeforeScenePaused = allGameObjects.Where(x => isActiveAndEnabled).ToList();
foreach (var go in activeGameObjectsBeforeScenePaused)
{
go.SetActive(false);
}
}