Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Scripts/Utilities/Touch.as"
- const float TOUCH_SENSITIVITY = 2;
- const float MAX_BALLOON_HEIGHT = 120.0f;
- Node@ characterNode;
- Node@ balloonNode;
- Node@ arrowUINode;
- Node@ cameraNode;
- Sprite@ cursor;
- // Air UI options
- LineEdit@ universalGasConstant;
- LineEdit@ airMolarMass;
- LineEdit@ normalAtmospherePressure;
- LineEdit@ outsideAirTemperature;
- LineEdit@ insideAirTemperature;
- // Balloon UI options
- LineEdit@ balloonVolume;
- LineEdit@ balloonMass;
- LineEdit@ basketMass;
- LineEdit@ gravityConstant;
- Button@ airResetButton;
- Button@ restartButton;
- Text@ questText;
- Sprite@ compass;
- const int CTRL_FORWARD = 1;
- const int CTRL_BACK = 2;
- const int CTRL_LEFT = 4;
- const int CTRL_RIGHT = 8;
- const int CTRL_JUMP = 16;
- const int CTRL_INTERACT = 32;
- const int CTRL_TEMP_UP = 64;
- const int CTRL_TEMP_DOWN = 128;
- const float MOVE_FORCE = 1.0f;
- const float INAIR_MOVE_FORCE = 0.02f;
- const float BRAKE_FORCE = 0.5f;
- const float JUMP_FORCE = 7.0f;
- const float YAW_SENSITIVITY = 0.1f;
- const float INAIR_THRESHOLD_TIME = 0.1f;
- bool firstPerson = false; // First person camera flag
- const float maxDistance = 10.0f;
- Array<Vector3> windDirs(5);
- Array<Vector3> windChangesHeight(5);
- Array<Vector3> dirsLong(5);
- Array<Vector3> dirsResult(6);
- Vector3 goalPosition = Vector3(0.0f, 0.0f, 0.0f);
- class Character : ScriptObject
- {
- // Character controls.
- Controls controls;
- Controls previousControl;
- // Grounded flag for movement.
- bool onGround = false;
- // Jump flag.
- bool okToJump = true;
- // In air timer. Due to possible physics inaccuracy, character can be off ground for max. 1/10 second and still be allowed to move.
- float inAirTimer = 0.0f;
- // Is in interact mode ?
- bool isInteract = false;
- // Float time step interacted
- float interactedTimeElapsed = 0.0f;
- void Start()
- {
- SubscribeToEvent(node, "NodeCollision", "HandleNodeCollision");
- // Subscribe to Update event for setting the character controls before physics simulation
- SubscribeToEvent("Update", "HandleUpdate");
- SubscribeToEvent("Interact", "HandleInteract");
- compass = cast<Sprite>(ui.root.GetChild("Compass", true));
- }
- void HandleUpdate(StringHash eventType, VariantMap& eventData)
- {
- Character@ character = cast<Character>(this);
- if (character is null)
- return;
- previousControl = character.controls;
- // Clear previous controls
- character.controls.Set(CTRL_FORWARD | CTRL_BACK | CTRL_LEFT | CTRL_RIGHT | CTRL_JUMP | CTRL_INTERACT | CTRL_TEMP_UP | CTRL_TEMP_DOWN, false);
- // Update controls using keys (desktop)
- if (ui.focusElement is null)
- {
- character.controls.Set(CTRL_INTERACT, input.keyDown[KEY_E]);
- //if(!isInteract)
- //{
- character.controls.Set(CTRL_FORWARD, input.keyDown[KEY_W]);
- character.controls.Set(CTRL_BACK, input.keyDown[KEY_S]);
- character.controls.Set(CTRL_LEFT, input.keyDown[KEY_A]);
- character.controls.Set(CTRL_RIGHT, input.keyDown[KEY_D]);
- character.controls.Set(CTRL_JUMP, input.keyDown[KEY_SPACE]);
- character.controls.Set(CTRL_TEMP_UP, input.keyDown[KEY_O]);
- character.controls.Set(CTRL_TEMP_DOWN, input.keyDown[KEY_L]);
- //}
- character.controls.yaw += input.mouseMoveX * YAW_SENSITIVITY;
- character.controls.pitch += input.mouseMoveY * YAW_SENSITIVITY;
- // Limit pitch
- character.controls.pitch = Clamp(character.controls.pitch, -80.0f, 80.0f);
- // Set rotation already here so that it's updated every rendering frame instead of every physics frames
- node.rotation = Quaternion(character.controls.yaw, Vector3(0.0f, 1.0f, 0.0f));
- if(compass !is null)
- {
- Vector3 angles = node.rotation.eulerAngles;
- compass.rotation = -angles.y;
- }
- // Switch between 1st and 3rd person
- if (input.keyPress[KEY_F])
- firstPerson = !firstPerson;
- }
- }
- void Load(Deserializer& deserializer)
- {
- controls.yaw = deserializer.ReadFloat();
- controls.pitch = deserializer.ReadFloat();
- }
- void Save(Serializer& serializer)
- {
- serializer.WriteFloat(controls.yaw);
- serializer.WriteFloat(controls.pitch);
- }
- void HandleNodeCollision(StringHash eventType, VariantMap& eventData)
- {
- VectorBuffer contacts = eventData["Contacts"].GetBuffer();
- while (!contacts.eof)
- {
- Vector3 contactPosition = contacts.ReadVector3();
- Vector3 contactNormal = contacts.ReadVector3();
- float contactDistance = contacts.ReadFloat();
- float contactImpulse = contacts.ReadFloat();
- // If contact is below node center and pointing up, assume it's a ground contact
- if (contactPosition.y < (node.position.y + 1.0f))
- {
- float level = contactNormal.y;
- if (level > 0.75)
- onGround = true;
- }
- }
- }
- void FixedUpdate(float timeStep)
- {
- if(insideAirTemperature is null)
- return;
- if(isInteract)
- {
- interactedTimeElapsed += timeStep;
- }
- /// \todo Could cache the components for faster access instead of finding them each frame
- RigidBody@ body = node.GetComponent("RigidBody");
- AnimationController@ animCtrl = node.GetComponent("AnimationController", true);
- // Update the in air timer. Reset if grounded
- if (!onGround)
- inAirTimer += timeStep;
- else
- inAirTimer = 0.0f;
- // When character has been in air less than 1/10 second, it's still interpreted as being on ground
- bool softGrounded = inAirTimer < INAIR_THRESHOLD_TIME;
- if(!isInteract)
- {
- // Update movement & animation
- Quaternion rot = node.rotation;
- Vector3 moveDir(0.0f, 0.0f, 0.0f);
- Vector3 velocity = body.linearVelocity;
- // Velocity on the XZ plane
- Vector3 planeVelocity(velocity.x, 0.0f, velocity.z);
- if (controls.IsDown(CTRL_FORWARD))
- moveDir += Vector3(0.0f, 0.0f, 1.0f);
- if (controls.IsDown(CTRL_BACK))
- moveDir += Vector3(0.0f, 0.0f, -1.0f);
- if (controls.IsDown(CTRL_LEFT))
- moveDir += Vector3(-1.0f, 0.0f, 0.0f);
- if (controls.IsDown(CTRL_RIGHT))
- moveDir += Vector3(1.0f, 0.0f, 0.0f);
- // Normalize move vector so that diagonal strafing is not faster
- if (moveDir.lengthSquared > 0.0f)
- moveDir.Normalize();
- // If in air, allow control, but slower than when on ground
- body.ApplyImpulse(rot * moveDir * (softGrounded ? MOVE_FORCE : INAIR_MOVE_FORCE));
- if (softGrounded)
- {
- // When on ground, apply a braking force to limit maximum ground velocity
- Vector3 brakeForce = -planeVelocity * BRAKE_FORCE;
- body.ApplyImpulse(brakeForce);
- // Jump. Must release jump control inbetween jumps
- if (controls.IsDown(CTRL_JUMP))
- {
- if (okToJump)
- {
- body.ApplyImpulse(Vector3(0.0f, 1.0f, 0.0f) * JUMP_FORCE);
- okToJump = false;
- //animCtrl.PlayExclusive("Characters/Jack/Animation/Jack_Walk.ani", 0, false, 0.2f);
- animCtrl.Stop("Characters/Jack/Animation/Jack_Walk.ani", 0.1f);
- //animCtrl.SetTime("Characters/Jack/Animation/Jack_Walk.ani", 0.0f);
- //animCtrl.PlayExclusive("Characters/Jack/Animation/Jack_Walk.ani", 0, false, 0.0f);
- }
- }
- else
- okToJump = true;
- }
- if (!onGround)
- {
- animCtrl.Stop("Characters/Jack/Animation/Jack_Walk.ani", 0.1f);
- }
- else
- {
- // Play walk animation if moving on ground, otherwise fade it out
- if (softGrounded && !moveDir.Equals(Vector3(0.0f, 0.0f, 0.0f)))
- {
- animCtrl.PlayExclusive("Characters/Jack/Animation/Jack_Walk.ani", 0, true, 0.2f);
- // Set walk animation speed proportional to velocity
- animCtrl.SetSpeed("Characters/Jack/Animation/Jack_Walk.ani", 0.9f);
- }
- else
- //animCtrl.PlayExclusive("Models/Mutant/Mutant_Idle0.ani", 0, true, 0.2f);
- animCtrl.Stop("Characters/Jack/Animation/Jack_Walk.ani", 0.2f);
- }
- }
- //if(isInteract) {
- float temp = insideAirTemperature.text.ToFloat();
- if(controls.IsDown(CTRL_TEMP_UP))
- {
- temp += 1.0f;
- }
- if(controls.IsDown(CTRL_TEMP_DOWN))
- {
- temp -= 1.0f;
- }
- insideAirTemperature.text = String(temp);
- //}
- // Reset grounded flag for next frames
- onGround = false;
- }
- void HandleInteract(StringHash eventType, VariantMap& eventData)
- {
- bool result = eventData["result"].GetBool();
- String from = eventData["from"].GetString();
- if(from.Contains("balloon", false))
- {
- if(result)
- {
- RigidBody@ body = node.GetComponent("RigidBody");
- body.kinematic = true;
- body.enabled = false;
- balloonNode.AddChild(node, node.id);
- Quaternion rot = node.worldRotation;
- node.position = Vector3();
- node.position += Vector3(0.0f, 0.05f, 0.0f);
- node.scale = Vector3(0.1f, 0.1f, 0.1f);
- node.Rotate(rot);
- isInteract = true;
- }
- else
- {
- // Thenn we have interacted with balloon spreviouslys
- // we suppose that att least 1/2 sec should elapsed in order to get out from basket
- if(isInteract && interactedTimeElapsed > 0.5f)
- {
- RigidBody@ body = node.GetComponent("RigidBody");
- body.kinematic = false;
- body.enabled = true;
- //basket.RemoveChild(node);
- node.scale = Vector3(0.5f, 0.5f, 0.5f);
- scene.AddChild(node, node.id);
- Vector3 dir = node.worldDirection;
- Vector3 balloonPos = balloonNode.worldPosition;
- balloonPos.z += dir.z * 0.5f;
- node.position = balloonPos;
- isInteract = false;
- interactedTimeElapsed = 0.0f;
- }
- }
- }
- }
- }
- class Balloon : ScriptObject
- {
- float currentHeight;
- float maxHeight;
- float currentTemp;
- float maxTemp;
- float timeElapsed = 0.0f;
- float timeNeedToPass = Random(2.0f, 6.0f);
- int currentNeedToReachDis = 1;
- RigidBody@ balloonBody;
- String currentObjectInInteract = "";
- // Character controls.
- Controls controls;
- // Grounded flag for movement.
- bool onGround = false;
- float inAirTimer = 0.0f;
- void Start()
- {
- balloonNode = scene.GetChild("Balloon_1", true);
- balloonBody = node.GetComponent("RigidBody");
- SubscribeToEvent(node, "NodeCollision", "HandleNodeCollision");
- // Subscribe to Update event for setting the character controls befosre physics simulation
- SubscribeToEvent("Update", "HandleUpdate");
- RegisterEventName("Interact");
- SubscribeToEvent("Interact", "HandleInteract");
- currentHeight = 0.0f;
- maxHeight = 30000.0f;
- currentTemp = 0.0f;
- maxTemp = 61.0f;
- }
- void HandleUpdate(StringHash eventType, VariantMap& eventData)
- {
- Balloon@ balloon = cast<Balloon>(this);
- if (balloon is null)
- return;
- // Clear previous controls
- balloon.controls.Set(CTRL_FORWARD | CTRL_BACK | CTRL_LEFT | CTRL_RIGHT | CTRL_JUMP, false);
- // Update controls using keys (desktop)
- if (ui.focusElement is null)
- {
- balloon.controls.Set(CTRL_FORWARD, input.keyDown[KEY_W]);
- balloon.controls.Set(CTRL_BACK, input.keyDown[KEY_S]);
- balloon.controls.Set(CTRL_LEFT, input.keyDown[KEY_A]);
- balloon.controls.Set(CTRL_RIGHT, input.keyDown[KEY_D]);
- balloon.controls.Set(CTRL_JUMP, input.keyDown[KEY_SPACE]);
- balloon.controls.yaw += input.mouseMoveX * YAW_SENSITIVITY;
- balloon.controls.pitch += input.mouseMoveY * YAW_SENSITIVITY;
- // Limit pitch
- balloon.controls.pitch = Clamp(balloon.controls.pitch, -80.0f, 80.0f);
- // Set rotation already here so that it's updated every rendering frame instead of every physics frame
- //node.rotation = Quaternion(balloon.controls.yaw, Vector3(0.0f, 1.0f, 0.0f));
- }
- }
- void HandlePostUpdate(StringHash eventType, VariantMap& eventData)
- {
- }
- void Load(Deserializer& deserializer)
- {
- controls.yaw = deserializer.ReadFloat();
- controls.pitch = deserializer.ReadFloat();
- }
- void Save(Serializer& serializer)
- {
- serializer.WriteFloat(controls.yaw);
- serializer.WriteFloat(controls.pitch);
- }
- void HandleNodeCollision(StringHash eventType, VariantMap& eventData)
- {
- VectorBuffer contacts = eventData["Contacts"].GetBuffer();
- while (!contacts.eof)
- {
- Vector3 contactPosition = contacts.ReadVector3();
- Vector3 contactNormal = contacts.ReadVector3();
- float contactDistance = contacts.ReadFloat();
- float contactImpulse = contacts.ReadFloat();
- // If contact is below node center and pointing up, assume it's a ground contact
- if (contactPosition.y < (node.position.y + 1.0f))
- {
- float level = contactNormal.y;
- if (level > 0.75)
- onGround = true;
- }
- }
- Node@ otherNode = cast<Node>(eventData["OtherNode"].GetPtr());
- if(otherNode.name.Contains("CheckZone", false))
- {
- CheckZone@ checkZoneComponent = cast<CheckZone>(otherNode.scriptObject);
- if(!checkZoneComponent.isChecked) {
- if(checkZoneComponent.checkZoneId == currentNeedToReachDis)
- {
- Print("COLLISION FOUND WITH " + checkZoneComponent.checkZoneId);
- currentNeedToReachDis += 1;
- questText.text = "Current index = " + currentNeedToReachDis;
- Vector3 newVel = balloonBody.linearVelocity;
- newVel.x = 0.0f;
- newVel.z = 0.0f;
- balloonBody.linearVelocity = newVel;
- arrowUINode.position = dirsResult[currentNeedToReachDis];
- }
- else
- {
- log.Error("Balloon miss one check zone!!!");
- }
- checkZoneComponent.isChecked = true;
- }
- }
- }
- void FixedUpdate(float timeStep)
- {
- if(airMolarMass is null)
- return;
- /// \todo Coould cache the components for fasster access instead of finding them each frames
- RigidBody@ body = node.GetComponent("RigidBody");
- float previousHeight = node.position.y;
- float currentHeight = node.position.y;
- currentTemp = outsideAirTemperature.text.ToFloat() - 273.0f;
- //Print(currentTemp);
- if(currentHeight >= 0.0f)
- {
- float absHeight = Abs(maxHeight - currentHeight);
- float normHeight = absHeight / maxHeight;
- normHeight = 1 - normHeight;
- float difTemp = Abs(maxTemp - currentTemp);
- float newTemp = difTemp * normHeight;
- Vector3 vel = body.linearVelocity;
- float currentOutSideTemp = outsideAirTemperature.text.ToFloat();
- float newCurrentOutSideTemp = currentOutSideTemp - 273.0f;
- if(vel.y >= 0)
- {
- newCurrentOutSideTemp -= 0.01f;
- }
- else
- {
- newCurrentOutSideTemp += 0.01f;
- }
- outsideAirTemperature.text = String((newCurrentOutSideTemp + 273.0f));
- //Print("normalAtmPressurse" + normalAtmPressure);
- }
- float normalPressureUpSea = 101325.0f;
- float newpressure = normalPressureUpSea * Pow(2.71828f, (-airMolarMass.text.ToFloat() * gravityConstant.text.ToFloat() * currentHeight) / (8.31f * outsideAirTemperature.text.ToFloat()));
- //Print("newpressure" + newpressure);
- normalAtmospherePressure.text = String(newpressure);
- // Update the in air timer. Reset if grounded
- if (!onGround)
- inAirTimer += timeStep;
- else
- inAirTimer = 0.0f;
- // 1. calcualte basket + balloon weight
- float insideAirDensity = normalAtmospherePressure.text.ToFloat() / (universalGasConstant.text.ToFloat() * insideAirTemperature.text.ToFloat());
- //Print("insideAirDensity = " + insideAirDensity);
- //log.Debug(insideAirDensity);
- float balloonWeight = ((balloonMass.text.ToFloat() + basketMass.text.ToFloat()) * gravityConstant.text.ToFloat()) + (insideAirDensity * balloonVolume.text.ToFloat() * gravityConstant.text.ToFloat());
- //Print("balloonWeight = " + balloonWeight);
- body.mass = ((balloonMass.text.ToFloat() + basketMass.text.ToFloat())) + (insideAirDensity * balloonVolume.text.ToFloat());
- //Print("balloonMass = " + body.mass);
- float outsideAirDensity = normalAtmospherePressure.text.ToFloat() / (universalGasConstant.text.ToFloat() * outsideAirTemperature.text.ToFloat());
- //Print("outsideAirDensity = " + outsideAirDensity);
- float archimedForce = outsideAirDensity * gravityConstant.text.ToFloat() * balloonVolume.text.ToFloat();
- //Print("archimedForce = " + archimedForce);
- float buoyanceForce = archimedForce - balloonWeight;
- //Print("buoyanceForce = " + buoyanceForce);
- body.ApplyForce(Vector3(0.0f, archimedForce, 0.0f));
- float normalizedHeight = currentHeight / MAX_BALLOON_HEIGHT;
- int windDirIndex = int(5 * normalizedHeight);
- //Print("windDirIndex = " + windDirIndex);
- float windForce = Random(50.0f, 50.0f);
- windDirIndex = 0;
- //if(!currentObjectInInteract.empty)
- //{
- timeElapsed += timeStep;
- if(timeElapsed > timeNeedToPass) {
- //Print("Check1");
- Quaternion windDir;
- windDir.FromEulerAngles(windChangesHeight[windDirIndex].x, windChangesHeight[windDirIndex].y, windChangesHeight[windDirIndex].z);
- Vector3 windForceWithDir = windDir * Vector3(0.0f, 0.0f, windForce);
- //Print(windForceWithDir.x + " " + windForceWithDir.y + " " + windForceWithDir.z);
- //debugRenderer.AddLine(node.position + Vector3(0.0f, 1.0f, 0.0f), windForceWithDir, Color(1.0f, 1.0f, 1.0f, 1.0f));
- Quaternion q;
- q.FromLookRotation(dirsResult[currentNeedToReachDis].Normalized());
- Vector3 newImpules = dirsResult[currentNeedToReachDis];
- newImpules.y = node.position.y;
- newImpules = newImpules - node.position;
- Print(newImpules.x + " " + newImpules.y + " " + newImpules.z);
- body.ApplyForce(newImpules);
- debugRenderer.AddLine(Vector3(node.position.x, node.position.y, node.position.z), newImpules, Color(0.0f, 0.0f, 0.0f, 1.0f));
- timeElapsed = 0.0f;
- timeNeedToPass = Random(0.0f, 1.0f);
- }
- //}
- }
- void HandleInteract(StringHash eventType, VariantMap& eventData)
- {
- String interactFrom = eventData["from"].GetString();
- if(interactFrom.Contains("player", false))
- {
- if(currentObjectInInteract.empty)
- {
- // sit in balloon
- currentObjectInInteract = interactFrom;
- Print("Balloon start interfact from " + interactFrom);
- VariantMap data;
- data["from"] = "balloon";
- data["result"] = true;
- SendEvent("Interact", data);
- }
- else if(currentObjectInInteract == interactFrom)
- {
- if(eventData["exit"].GetBool())
- {
- // get out of balloon
- currentObjectInInteract = "";
- Print("Balloon end interfact from " + interactFrom);
- VariantMap data;
- data["from"] = "balloon";
- data["result"] = false;
- SendEvent("Interact", data);
- }
- }
- }
- }
- }
- class CameraScript : ScriptObject
- {
- void Start()
- {
- characterNode = scene.GetChild("Character", true);
- cameraNode = node;
- cursor = cast<Sprite>(ui.root.GetChild("Game_Cursor", true));
- if(cursor is null)
- Print("Failed to find cursor");
- else
- Print("Cursor is finded !");
- // Subscribe to PostUpdate event for updating the camera position after physics simulation
- SubscribeToEvent("PostUpdate", "HandlePostUpdate");
- SubscribeToEvent("MouseWheel", "MouseWheelUpdate");
- }
- void HandlePostUpdate(StringHash eventType, VariantMap& eventData)
- {
- if (characterNode is null)
- return;
- Character@ character = cast<Character>(characterNode.scriptObject);
- if (character is null)
- return;
- // Get camera lookat dir from character yaw + pitch
- Quaternion rot = characterNode.rotation;
- Quaternion dir = rot * Quaternion(character.controls.pitch, Vector3(1.0f, 0.0f, 0.0f));
- // Turn head to camera pitch, but limit to avoid unnatural animation
- Node@ headNode = characterNode.GetChild("Bip01_Head", true);
- float limitPitch = Clamp(character.controls.pitch, -45.0f, 45.0f);
- Quaternion headDir = rot * Quaternion(limitPitch, Vector3(1.0f, 0.0f, 0.0f));
- // This could be expanded to look at an arbitrary target, now just look at a point in front
- Vector3 headWorldTarget = headNode.worldPosition + headDir * Vector3(0.0f, 0.0f, 1.0f);
- headNode.LookAt(headWorldTarget, Vector3(0.0f, 1.0f, 0.0f));
- headNode.Rotate(Quaternion(0.0f, 90.0f, 90.0f));
- if (firstPerson)
- {
- // First person camera: position to the head bone + offset slightly forward & up
- if(character.isInteract)
- {
- cameraNode.position = headNode.worldPosition + rot * Vector3(0.0f, 0.403f, 0.23f);//rot * Vector3(0.0f, 0.0f, 0.01f);
- cameraNode.rotation = dir;
- }
- else
- {
- cameraNode.position = headNode.worldPosition + rot * Vector3(0.0f,0.425f, 0.025f);//rot * Vector3(0.0f, 0.0f, 0.01f);
- cameraNode.rotation = dir;
- }
- Vector3 hitPos;
- RigidBody@ hitDrawable;
- // IntVector2 pos = cursor.screenPosition;
- IntVector2 pos = cursor.screenPosition;
- // Check the cursor is visible and there is no UI element in front of the cursor
- //if (ui.GetElementAt(pos, true) !is null)
- // return;
- Camera@ camera = cameraNode.GetComponent("Camera");
- // pos = camera.WorldToScreenPoint(headNode.worldPosition);
- float posx = float(pos.x) / float(graphics.width);
- float posy = float(pos.y) / float(graphics.height);
- Ray cameraRay = camera.GetScreenRay(posx, posy);
- //camera.GetScreenRay(float(pos.x) / graphics.width, float(pos.y) / graphics.height);
- if(character.controls.IsDown(CTRL_INTERACT) && character.isInteract)
- {
- VariantMap sendData;
- sendData["from"] = "player";
- sendData["exit"] = true;
- SendEvent("Interact", sendData);
- }
- else
- {
- // Pick only geometry objects, not eg. zones or lights, only get the first (closest) hit
- // Note the convenience accessor to scene's Octree component sss
- PhysicsRaycastResult result = scene.physicsWorld.RaycastSingle(cameraRay, 0.4f);
- if (result.body !is null)
- {
- //Print("Drawable is not null!");
- hitPos = result.position;
- hitDrawable = result.body;
- if(hitDrawable.node.HasTag("Interact"))
- {
- VariantMap sendData;
- sendData["from"] = "player";
- sendData["exit"] = false;
- if(character.controls.IsDown(CTRL_INTERACT))
- {
- if(!character.isInteract)
- {
- SendEvent("Interact", sendData);
- }
- else
- {
- sendData["exit"] = true;
- SendEvent("Interact", sendData);
- }
- }
- //Print(hitDrawable.node.name);
- }
- else{
- Print(hitDrawable.node.name);
- }
- }
- return;
- }
- }
- else
- {
- // Third person camera: position behind the character
- Vector3 aimPoint = characterNode.worldPosition + rot * Vector3(0.0f, 0.8f, 0.0f); ///// You can modify x Vector3 value to translate the fixed character position (indicative range[-2;2])
- // Collide camera ray with static physics objects (layer bitmask 2) to ensure we see the character properly
- Vector3 rayDir = dir * Vector3(0.0f, 0.0f, -1.0f); // For indoor scenes you can use dir * Vector3(0.0, 0.0, -0.5) to prevent camera from crossing the walls
- float rayDistance = cameraDistance;
- if(!character.isInteract)
- {
- PhysicsRaycastResult result = scene.physicsWorld.RaycastSingle(Ray(aimPoint, rayDir), rayDistance, 2);
- if (result.body !is null)
- rayDistance = Min(rayDistance, result.distance);
- }
- rayDistance = Clamp(rayDistance, CAMERA_MIN_DIST, cameraDistance);
- cameraNode.position = aimPoint + rayDir * rayDistance;
- cameraNode.rotation = dir;
- Vector3 pos = cameraNode.position;
- pos.y = Clamp(pos.y, 0.05f, 10000.0f);
- cameraNode.position = pos;
- }
- }
- void MouseWheelUpdate(StringHash eventType, VariantMap& eventData)
- {
- float wheel = eventData["Wheel"].GetFloat();
- cameraDistance += wheel * 0.1f;
- cameraDistance = Clamp(cameraDistance, CAMERA_MIN_DIST, 100.0f);
- }
- }
- class HotAirBalloonUI : ScriptObject
- {
- void Start()
- {
- universalGasConstant = cast<LineEdit>(ui.root.GetChild("Edit_Universal_Gas_Constant", true));
- airMolarMass = cast<LineEdit>(ui.root.GetChild("Edit_Air_Molar_Mass", true));
- normalAtmospherePressure = cast<LineEdit>(ui.root.GetChild("Edit_Normal_Air_Pressure", true));
- outsideAirTemperature = cast<LineEdit>(ui.root.GetChild("Edit_Outside_Air_Temperature", true));
- insideAirTemperature = cast<LineEdit>(ui.root.GetChild("Edit_Inside_Air_Temperature", true));
- balloonVolume = cast<LineEdit>(ui.root.GetChild("Edit_Balloon_Volume", true));
- balloonMass = cast<LineEdit>(ui.root.GetChild("Edit_Balloon_Mass", true));
- basketMass = cast<LineEdit>(ui.root.GetChild("Edit_Balloon_Basket_Mass", true));
- gravityConstant = cast<LineEdit>(ui.root.GetChild("Edit_Gravity_Constant", true));
- airResetButton = cast<Button>(ui.root.GetChild("Button_Air_Reset", true));
- restartButton = cast<Button>(ui.root.GetChild("Restart_Button", true));
- questText = cast<Text>(ui.root.GetChild("Quest_Text", true));
- if(gravityConstant is null) {
- Print("Failed to init UI");
- }
- else {
- Print("UI is initialized !");
- }
- if(airResetButton !is null)
- SubscribeToEvent(airResetButton, "Pressed", "HandleAirResetClick");
- if(restartButton !is null)
- SubscribeToEvent(restartButton, "Pressed", "HandleRestartClick");
- }
- void HandleAirResetClick(StringHash eventType, VariantMap& eventData)
- {
- universalGasConstant.text = "287.05";
- airMolarMass.text = "0.029";
- normalAtmospherePressure.text = "101325";
- outsideAirTemperature.text = "273";
- insideAirTemperature.text = "273";
- }
- void HandleRestartClick(StringHash eventType, VariantMap& eventData)
- {
- //CalculateNewGoal();
- }
- }
- class ArrowUI : ScriptObject
- {
- float timeElapsed;
- bool isDirChanged = false;
- void Start()
- {
- dirsResult.Clear();
- dirsLong.Clear();
- dirsLong.Push(balloonNode.position);
- dirsResult.Push(balloonNode.position);
- goalPosition = balloonNode.position;
- for(int i = 0; i < 5; i++)
- {
- float yAngle;
- if(i % 2 == 0) {
- windDirs[i] = Vector3(0.0f, Random(0, 30), 0.0f);
- //Print("windDirs ODD " + i + " = " + windDirs[i].y);
- }
- else
- {
- windDirs[i] = Vector3(0.0f, Random(340, 360), 0.0f);
- //Print("windDirs EVEN " + i + " = " + windDirs[i].y);
- }
- windChangesHeight[i] = windDirs[i];
- //Print("windChangesHeight Y0" + i + " = " + windChangesHeight[i].x);
- //Print("windChangesHeight Y1" + i + " = " + windChangesHeight[i].y);
- dirsLong.Push(Vector3(dirsLong[i].x, 0.0f, dirsLong[i].z + Random(50, 500)));
- //Print("dirsLong " + i + " = " + dirsLong[i].z);
- Quaternion dirRot;
- dirRot.FromEulerAngles(windDirs[i].x, windDirs[i].y, windDirs[i].z);
- Vector3 goalPartDistance = dirRot * dirsLong[i + 1];
- Node@ terrain = scene.GetChild("Terrain", true);
- Terrain@ terrainComponent = terrain.GetComponent("Terrain", true);
- Print("goalpartDistance X" + i + " = " + goalPartDistance.x);
- Print("goalpartDistance Z" + i + " = " + goalPartDistance.z);
- float height = terrainComponent.GetHeight(goalPartDistance);
- Print("height = " + height);
- goalPartDistance.y = height;
- dirsResult.Push(goalPartDistance);
- }
- goalPosition = dirsResult[5];
- for(int i = 0; i < 5; i++)
- {
- //--- Shuffle elements by randomly exchanging each with one other.
- int r = int(Random(0, 5)); // generate a random position
- Print(r);
- //Vector3 temp = windChangesHeight[i]; windChangesHeight[i] = windChangesHeight[r]; windChangesHeight[r] = temp;
- }
- arrowUINode = scene.GetChild("ArrowUI", true);
- Node@ terrain = scene.GetChild("Terrain", true);
- Terrain@ terrainComponent = terrain.GetComponent("Terrain", true);
- //CalculateNewGoal();
- Node@ checkNode = scene.GetChild("CheckNode", true);
- Array<Node@> checkNodes = scene.GetNodesWithTag("CheckZone");
- // More compact loop, where condition is checked before the logic is executed
- for( int n = 0; n < checkNodes.length; n++ )
- {
- // Print("Node it " + n);
- checkNode.RemoveChild(checkNodes[n]);
- }
- //checkNode.RemoveAllChildren();
- for(int i = 0; i < 5; i++)
- {
- Node@ checkZone = checkNode.CreateChild("CheckZone_" + i);
- checkZone.AddTag("CheckZone");
- checkZone.position = dirsResult[i + 1];
- RigidBody@ body = checkZone.CreateComponent("RigidBody");
- body.useGravity = false;
- body.trigger = true;
- CollisionShape@ shape = checkZone.CreateComponent("CollisionShape");
- shape.SetBox(Vector3(200.0f, 150.0f, 1.0f));
- // Create the character logic object, which takes care of steering the rigidbody
- checkZone.CreateScriptObject(scriptFile, "CheckZone");
- CheckZone@ checkZoneComponent = cast<CheckZone>(checkZone.scriptObject);
- checkZoneComponent.checkZoneId = i + 1;
- }
- isDirChanged = false;
- timeElapsed = 0.0f;
- node.position = dirsResult[1];
- float height = terrainComponent.GetHeight(node.position);
- Vector3 newPos = node.position;
- newPos.y = height + 25.0f;
- node.position = newPos;
- SubscribeToEvent("Update", "HandleUpdate");
- //SubscribeToEvent("BeginFrame", "HandlePreUpdate");
- //SubscribeToEvent(node, "NodeCollision", "HandleNodeCollision");
- }
- void HandleUpdate(StringHash eventType, VariantMap& eventData)
- {
- for(int i = 0; i < 5; i++)
- {
- debugRenderer.AddLine(dirsResult[i], dirsResult[i + 1], Color(1.0f, 1.0f, 1.0f, 1.0f));
- }
- float timeStep = eventData["TimeStep"].GetFloat();
- timeElapsed += timeStep;
- if(timeElapsed >= 1.0f)
- {
- isDirChanged = !isDirChanged;
- timeElapsed = 0.0f;
- }
- Vector3 pos = node.position;
- if(!isDirChanged)
- {
- pos.y += 0.01f;
- }
- else
- {
- pos.y -= 0.01f;
- }
- node.position = pos;
- }
- void HandleNodeCollision(StringHash eventType, VariantMap& eventData)
- {
- VectorBuffer contacts = eventData["Contacts"].GetBuffer();
- while (!contacts.eof)
- {
- Vector3 contactPosition = contacts.ReadVector3();
- Vector3 contactNormal = contacts.ReadVector3();
- float contactDistance = contacts.ReadFloat();
- float contactImpulse = contacts.ReadFloat();
- // If contact is below node center and pointing up, assume it's a ground contact
- if (contactPosition.y < (node.position.y + 1.0f))
- {
- float level = contactNormal.y;
- if (level > 0.75)
- {
- Vector3 newPos = node.position;
- newPos.y = contactPosition.y + 3.0f;
- //Print("newPos = " + newPos.y);
- node.position = newPos;
- }
- }
- }
- }
- }
- class CheckZone : ScriptObject
- {
- int checkZoneId = 1;
- bool isChecked = false;
- }
Advertisement
Add Comment
Please, Sign In to add comment