I tried to move oxygen between rooms based on the method of depressurization of the room, but it did not work. I would be grateful if you can explain the logic, preferably with examples. I have areas of triggers in the rooms. The button creates a trigger that switches the booleans that trigger the methods. I apologize for the large amount of code, I'm already completely lost and do not know what to do...
Room class:
public class Room : MonoBehaviour
{
[Foldout("Oxygen")] [Range(0.0f, 100.0f)]
public float room_curOxygen = 100f, room_maxOxygen = 100f, room_maxRemovedOxygen = 100f;
[Foldout("Stats multipliers")] [Range(0, 25)]
public int room_addOxygenStep, room_decreaseOxygenStep;
[ReadOnly]
public float room_minOxygen, room_minRemovedOxygen = 0f;
public float decreaseCurrentAvg;
public float room_removedOxygen;
private GameObject player;
private CharacterController characterController;
public GameObject roomUI;
private TMP_Text roomUI_oxygenLevelText, roomUI_removedOxygen;
public bool isRoomContainsOxygen;
public bool isOxygenDecreasing = false;
public bool canTransfer = false;
public OxygenTrigger oxygenTrigger;
void Start()
{
roomUI_oxygenLevelText = roomUI.GetComponent<RoomUI>().oxygenLevelText;
roomUI_removedOxygen = roomUI.GetComponent<RoomUI>().removedOxygenText;
player = GameObject.FindGameObjectWithTag("Player");
characterController = player.GetComponent<CharacterController>();
}
void Update()
{
if (room_curOxygen > 0)
{
isRoomContainsOxygen = true;
}
else
{
isRoomContainsOxygen = false;
}
}
private void OnTriggerStay(Collider other)
{
if (other.gameObject.tag == "Player")
{
characterController.inRoom = true;
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == "Player")
{
characterController.inRoom = false;
}
}
Button class:
public class InteractableButton : MonoBehaviour
{
public bool open = false;
private Animator doorAnimator;
public GameObject prefab_oxygenTrigger, triggersSpawnPoint;
private GameObject instOxygenTrigger;
private GameObject roomZone;
private Room room;
private void Start()
{
doorAnimator = transform.parent.GetComponent<Animator>();
roomZone = transform.parent.transform.parent.gameObject.transform.GetChild(1).gameObject;
room = roomZone.GetComponent<Room>();
}
public void DoorFunc()
{
bool alreadyChecked = false;
if (open) //closing door
{
doorAnimator.SetBool("doorOpened", false);
open = false;
alreadyChecked = true;
Destroy(instOxygenTrigger);
room.isOxygenDecreasing = false;
print($"<color=#CE7E00>Room oxygen ADD!</color>");
}
if (!open && !alreadyChecked) //opening door
{
doorAnimator.SetBool("doorOpened", true);
open = true;
instOxygenTrigger = Instantiate(prefab_oxygenTrigger, triggersSpawnPoint.transform);
print($"<color=#CE7E00>Room oxygen DECREASING!</color>");
}
}
}
OxygenTrigger class:
public class OxygenTrigger : MonoBehaviour
{
IEnumerator room_decreaseOxygen, room_addOxygen;
private GameObject roomZone;
private GameObject contactedRoomZone;
private Room room;
private Room contactedRoom;
void Start()
{
roomZone = transform.parent.transform.parent.gameObject;
room = roomZone.GetComponent<Room>();
}
private void Update()
{
if (room.canTransfer) TransferOxygen();
}
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag == "openZone")
{
room.isOxygenDecreasing = true;
}
if(other.gameObject.tag == "roomZone")
{
contactedRoom = other.gameObject.GetComponent<Room>();
room.isOxygenDecreasing = true;
contactedRoom.isOxygenDecreasing = true;
print(contactedRoom.name);
room.canTransfer = true;
contactedRoom.canTransfer = true;
}
}
private void OnTriggerExit(Collider other)
{
if(other.gameObject.tag == "roomZone")
{
room.isOxygenDecreasing = false;
room.canTransfer = false;
}
}
public void TransferOxygen()
{
room.room_curOxygen -= contactedRoom.room_curOxygen * Time.deltaTime / 2;
room.room_curOxygen = contactedRoom.room_curOxygen * Time.deltaTime / 2;
contactedRoom.room_curOxygen -= room.room_curOxygen * Time.deltaTime / 2;
contactedRoom.room_curOxygen = room.room_curOxygen * Time.deltaTime / 2;
}
}
CodePudding user response:
Despite the rest of the code, one thing stands out:
You seem to be adding and removing your values to and from the exact same room(s) in
room.room_curOxygen -= contactedRoom.room_curOxygen * Time.deltaTime / 2;
room.room_curOxygen = contactedRoom.room_curOxygen * Time.deltaTime / 2;
contactedRoom.room_curOxygen -= room.room_curOxygen * Time.deltaTime / 2;
contactedRoom.room_curOxygen = room.room_curOxygen * Time.deltaTime / 2;
After those lines you have the exact same values as you had before (maybe with some floating point impressions).
I guess you would rather want to remove it from one and add it to the other.
First of all as target the rooms would equal their total pressure, so assuming both rooms have the same volume you would do e.g.
var totalOxigen = (room.room_curOxygen contactedRoom.room_curOxygen);
var targetOxigyenPerRoom = total / 2;
or if there are different rooms volumes you would need that information to actually calculate an equal share of the available oxygen accordin to their volume / maximum oxygen
var roomTargetOxigen = targetOxigyenPerRoom * room.volume / contactedRoom.volume;
var contactedRoomTargetOxigen = targetOxigyenPerRoom * contactedRoom.volume / room.volume;
Then you have to move your current values towards the given target value(s). You can e.g. do that linear in fixed amount per second
room.room_curOxygen = Mathf.MoveTowards(room.room_curOxygen, targetOxigyenPerRoom, FIX_MOUNT_PER_SECOND * Tim.deltaTime);
contactedRoom.room_curOxygen = Mathf.MoveTowards(contactedRoom.room_curOxygen, targetOxigyenPerRoom, FIX_MOUNT_PER_SECOND * Tim.deltaTime);
or simply interpolate which is probably a bit more natural as higher pressure differences get probably balanced out faster
room.room_curOxygen = Mathf.Lerp(room.room_curOxygen, targetOxigyenPerRoom, 5 * Tim.deltaTime);
contactedRoom.room_curOxygen = Mathf.Lerp(contactedRoom.room_curOxygen, targetOxigyenPerRoom, 5 * Tim.deltaTime);
Where the 5 * Time.deltaTime
is actually an interpolation factor between 0
(return fully first parameter) and 1
(return fully second parameter) and 5
here is quite arbitrary, you can adjust it according to your needs. Higher value => faster interpolation.
The advantage in the second snippet is that high differences get balanced faster and the transfer becomes slower and slower the closer values are to the target