evelynshilosky

InteractionSystem - Part 6.3.4

May 2nd, 2025
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.78 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3.  
  4. public class InteractionSystem : MonoBehaviour
  5. {
  6.     public static InteractionSystem Instance { get; private set; }
  7.  
  8.     public Transform leftObjectHolder;
  9.     public Transform rightObjectHolder;
  10.     public LayerMask pickupLayer;
  11.     public float placementDistance = 5f;
  12.     public LayerMask placementLayerMask;
  13.     public float previewUpdateInterval = 0.1f;
  14.     public float placementHeightOffset = 0.1f;
  15.     public float rotationIncrement = 45f;
  16.     public Transform backpackWearPosition;
  17.  
  18.     private InventorySystem inventorySystem;
  19.     private PlayerMovement playerMovement;
  20.     private UIManager uiManager;
  21.  
  22.     private bool isPrecisionDrop = false;
  23.     private bool isRotating = false;
  24.     private Vector3 currentRotation;
  25.     private List<GameObject> previewObjects = new List<GameObject>();
  26.     private float lastPreviewUpdateTime;
  27.     private bool blockPickup = false;
  28.  
  29.     public Item currentBackpackItem;
  30.  
  31.     private void Start()
  32.     {
  33.         Instance = this;
  34.  
  35.         inventorySystem = InventorySystem.Instance;
  36.         playerMovement = GetComponent<PlayerMovement>();
  37.         uiManager = UIManager.Instance;
  38.         UpdateItemVisibility();
  39.     }
  40.  
  41.     private void Update()
  42.     {
  43.         if (Input.GetKeyDown(KeyCode.Tab))
  44.         {
  45.             if (uiManager.isInventoryOpen)
  46.             {
  47.                 uiManager.CloseInventory();
  48.             }
  49.             else if (inventorySystem.IsBackpackEquipped)
  50.             {
  51.                 uiManager.OpenInventory(inventorySystem.backpack);
  52.             }
  53.         }
  54.  
  55.         // Only allow these if the prompt is NOT open
  56.         if (isPrecisionDrop && !uiManager.inventoryPrompt.activeSelf)
  57.         {
  58.             UpdatePlacementPreview();
  59.  
  60.             if (Input.GetKeyDown(KeyCode.R))
  61.             {
  62.                 isRotating = !isRotating;
  63.                 uiManager.ShowRotationMessage(isRotating);
  64.                 if (isRotating && previewObjects.Count > 0)
  65.                     currentRotation = previewObjects[0].transform.rotation.eulerAngles;
  66.             }
  67.  
  68.             if (isRotating && previewObjects.Count > 0)
  69.             {
  70.                 if (Input.GetKey(KeyCode.Q))
  71.                     currentRotation.y -= rotationIncrement * Time.deltaTime;
  72.                 if (Input.GetKey(KeyCode.E))
  73.                     currentRotation.y += rotationIncrement * Time.deltaTime;
  74.                 if (Input.GetKey(KeyCode.Z))
  75.                     currentRotation.x -= rotationIncrement * Time.deltaTime;
  76.                 if (Input.GetKey(KeyCode.C))
  77.                     currentRotation.x += rotationIncrement * Time.deltaTime;
  78.  
  79.                 foreach (var obj in previewObjects)
  80.                     obj.transform.rotation = Quaternion.Euler(currentRotation);
  81.             }
  82.  
  83.             // F - Place both hands
  84.             if (Input.GetKeyDown(KeyCode.F))
  85.             {
  86.                 PlaceHandItem(true);  // left
  87.                 PlaceHandItem(false); // right
  88.                 isPrecisionDrop = false;
  89.                 isRotating = false;
  90.                 ClearPreviewObjects();
  91.                 UpdateItemVisibility();
  92.             }
  93.             // H - Place left hand only
  94.             else if (Input.GetKeyDown(KeyCode.H))
  95.             {
  96.                 PlaceHandItem(true);
  97.                 UpdatePreviewAfterSingleHandDrop();
  98.             }
  99.             // G - Place right hand only
  100.             else if (Input.GetKeyDown(KeyCode.G))
  101.             {
  102.                 PlaceHandItem(false);
  103.                 UpdatePreviewAfterSingleHandDrop();
  104.             }
  105.         }
  106.         else if (!isPrecisionDrop)
  107.         {
  108.             ClearPreviewObjects();
  109.         }
  110.  
  111.         if (Input.GetKeyDown(KeyCode.E) && currentBackpackItem != null && !inventorySystem.IsBackpackEquipped)
  112.         {
  113.             WearBackpack();
  114.         }
  115.     }
  116.  
  117.     private void PlaceHandItem(bool isLeftHand)
  118.     {
  119.         Item itemToDrop = isLeftHand ? inventorySystem.leftHandItem : inventorySystem.rightHandItem;
  120.         if (itemToDrop == null) return;
  121.  
  122.         int previewIndex = isLeftHand ? 0 : (previewObjects.Count > 1 ? 1 : 0);
  123.         if (previewObjects.Count == 0) return;
  124.  
  125.         GameObject itemObject = itemToDrop.gameObject;
  126.         itemObject.transform.SetParent(null);
  127.         itemObject.transform.position = previewObjects[previewIndex].transform.position;
  128.         itemObject.transform.rotation = previewObjects[previewIndex].transform.rotation;
  129.         itemObject.SetActive(true);
  130.  
  131.         Rigidbody rb = itemObject.GetComponent<Rigidbody>();
  132.         if (rb == null) rb = itemObject.AddComponent<Rigidbody>();
  133.         rb.isKinematic = false;
  134.         rb.useGravity = true;
  135.  
  136.         inventorySystem.UnequipItem(isLeftHand);
  137.         InteractableObject interactable = itemObject.GetComponent<InteractableObject>();
  138.         if (interactable != null) interactable.enabled = true;
  139.     }
  140.  
  141.     // After dropping one hand, update preview for the remaining item (if any)
  142.     private void UpdatePreviewAfterSingleHandDrop()
  143.     {
  144.         UpdateItemVisibility();
  145.         ClearPreviewObjects();
  146.         // If still holding an item, show preview for it
  147.         if (inventorySystem.leftHandItem != null || inventorySystem.rightHandItem != null)
  148.         {
  149.             UpdatePlacementPreview();
  150.         }
  151.         else
  152.         {
  153.             isPrecisionDrop = false;
  154.             isRotating = false;
  155.             ClearPreviewObjects();
  156.             UpdateItemVisibility();
  157.         }
  158.     }
  159.  
  160.  
  161.     private void PlaceItems()
  162.     {
  163.         for (int i = 0; i < previewObjects.Count; i++)
  164.         {
  165.             Item itemToDrop = null;
  166.             if (i == 0) itemToDrop = inventorySystem.leftHandItem;
  167.             if (i == 1) itemToDrop = inventorySystem.rightHandItem;
  168.  
  169.             if (itemToDrop != null)
  170.             {
  171.                 GameObject itemObject = itemToDrop.gameObject;
  172.                 itemObject.transform.SetParent(null);
  173.                 itemObject.transform.position = previewObjects[i].transform.position;
  174.                 itemObject.transform.rotation = previewObjects[i].transform.rotation;
  175.                 itemObject.SetActive(true);
  176.  
  177.                 Rigidbody rb = itemObject.GetComponent<Rigidbody>();
  178.                 if (rb == null) rb = itemObject.AddComponent<Rigidbody>();
  179.                 rb.isKinematic = false;
  180.                 rb.useGravity = true;
  181.  
  182.                 inventorySystem.UnequipItem(i == 0);
  183.                 InteractableObject interactable = itemObject.GetComponent<InteractableObject>();
  184.                 if (interactable != null) interactable.enabled = true;
  185.             }
  186.         }
  187.  
  188.         ClearPreviewObjects();
  189.         isPrecisionDrop = false;
  190.         isRotating = false;
  191.         UpdateItemVisibility();
  192.         // Optionally, show a "Precision drop disabled" message:
  193.         // uiManager.ShowPrecisionDropMessage(false);
  194.         blockPickup = true;
  195.         StartCoroutine(AllowPickupAfterFrame());
  196.     }
  197.  
  198.     private System.Collections.IEnumerator AllowPickupAfterFrame()
  199.     {
  200.         yield return null; // wait one frame
  201.         blockPickup = false;
  202.     }
  203.  
  204.     public void TogglePrecisionDrop()
  205.     {
  206.         if (!isPrecisionDrop &&
  207.             inventorySystem.leftHandItem == null &&
  208.             inventorySystem.rightHandItem == null)
  209.         {
  210.             Debug.Log("No items to place");
  211.             return;
  212.         }
  213.  
  214.         isPrecisionDrop = !isPrecisionDrop;
  215.         isRotating = false;
  216.  
  217.         if (isPrecisionDrop)
  218.         {
  219.             uiManager.ShowPrecisionDropMessage(true);
  220.         }
  221.         else
  222.         {
  223.             uiManager.ShowPrecisionDropMessage(false);
  224.             ClearPreviewObjects();
  225.         }
  226.  
  227.         UpdateItemVisibility();
  228.     }
  229.  
  230.     public void DropItem(bool isLeftHand)
  231.     {
  232.         Item itemToDrop = isLeftHand ? inventorySystem.leftHandItem : inventorySystem.rightHandItem;
  233.         if (itemToDrop != null)
  234.         {
  235.             GameObject itemObject = itemToDrop.gameObject;
  236.             itemObject.transform.SetParent(null);
  237.  
  238.             itemObject.transform.position = transform.position + transform.forward * 1f + transform.right * Random.Range(-0.5f, 0.5f);
  239.             itemObject.transform.rotation = Random.rotation;
  240.  
  241.             itemObject.SetActive(true);
  242.  
  243.             Rigidbody rb = itemObject.GetComponent<Rigidbody>();
  244.             if (rb == null) rb = itemObject.AddComponent<Rigidbody>();
  245.             rb.isKinematic = false;
  246.             rb.useGravity = true;
  247.             rb.AddForce(Vector3.down * 2f, ForceMode.Impulse);
  248.  
  249.             inventorySystem.UnequipItem(isLeftHand);
  250.  
  251.             InteractableObject interactable = itemObject.GetComponent<InteractableObject>();
  252.             if (interactable != null)
  253.             {
  254.                 interactable.enabled = true;
  255.             }
  256.  
  257.             playerMovement.UpdateCarryingAnimations();
  258.         }
  259.         UpdateItemVisibility();
  260.     }
  261.  
  262.     public void DropBothItems()
  263.     {
  264.         DropItem(true);
  265.         DropItem(false);
  266.     }
  267.  
  268.     // === END PUBLIC METHODS ===
  269.  
  270.     private void UpdatePlacementPreview()
  271.     {
  272.         if (Time.time - lastPreviewUpdateTime < previewUpdateInterval) return;
  273.         lastPreviewUpdateTime = Time.time;
  274.  
  275.         RaycastHit hit;
  276.         if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, placementDistance, placementLayerMask))
  277.         {
  278.             List<Item> itemsToPlace = new List<Item>();
  279.             if (inventorySystem.leftHandItem != null) itemsToPlace.Add(inventorySystem.leftHandItem);
  280.             if (inventorySystem.rightHandItem != null) itemsToPlace.Add(inventorySystem.rightHandItem);
  281.  
  282.             ClearPreviewObjects();
  283.  
  284.             Vector3 previewPosition = hit.point + hit.normal * (0.05f + placementHeightOffset);
  285.             Quaternion previewRotation = !isRotating ? Quaternion.LookRotation(hit.normal, Vector3.up) : Quaternion.Euler(currentRotation);
  286.  
  287.             for (int i = 0; i < itemsToPlace.Count; i++)
  288.             {
  289.                 GameObject previewObj = Instantiate(itemsToPlace[i].gameObject);
  290.                 DestroyImmediate(previewObj.GetComponent<Rigidbody>());
  291.                 DestroyImmediate(previewObj.GetComponent<Collider>());
  292.                 previewObj.AddComponent<Outline>();
  293.  
  294.                 previewObj.transform.position = previewPosition + Vector3.right * (i * 0.5f);
  295.                 previewObj.transform.rotation = previewRotation;
  296.  
  297.                 Outline outline = previewObj.GetComponent<Outline>();
  298.                 outline.OutlineMode = Outline.Mode.OutlineAll;
  299.                 outline.OutlineColor = Color.green;
  300.                 outline.OutlineWidth = 5f;
  301.  
  302.                 previewObjects.Add(previewObj);
  303.                 previewObj.SetActive(true);
  304.             }
  305.         }
  306.         else
  307.         {
  308.             ClearPreviewObjects();
  309.         }
  310.     }
  311.  
  312.     private void ClearPreviewObjects()
  313.     {
  314.         foreach (var obj in previewObjects)
  315.         {
  316.             Destroy(obj);
  317.         }
  318.         previewObjects.Clear();
  319.     }
  320.  
  321.     public void TryPickUpItem(InteractableObject interactable)
  322.     {
  323.         if (blockPickup) return;
  324.  
  325.         Item item = interactable.item;
  326.  
  327.         if (item.isBackpack && !inventorySystem.IsBackpackEquipped)
  328.         {
  329.             PickUpBackpack(item);
  330.         }
  331.         else
  332.         {
  333.             bool isLeftHand = inventorySystem.rightHandItem != null && inventorySystem.leftHandItem == null;
  334.             EquipItem(item, isLeftHand, item.isTwoHanded);
  335.             playerMovement.UpdateCarryingAnimations();
  336.  
  337.             // Explicitly ensure precision drop is OFF when picking up new items
  338.             if (isPrecisionDrop)
  339.             {
  340.                 isPrecisionDrop = false;
  341.                 uiManager.ShowPrecisionDropMessage(false);
  342.                 ClearPreviewObjects();
  343.             }
  344.         }
  345.     }
  346.  
  347.     private void PickUpBackpack(Item backpackItem)
  348.     {
  349.         bool isLeftHand = inventorySystem.rightHandItem != null && inventorySystem.leftHandItem == null;
  350.         EquipItem(backpackItem, isLeftHand, false);
  351.         currentBackpackItem = backpackItem;
  352.         uiManager.ShowBackpackPrompt(backpackItem);
  353.     }
  354.  
  355.     public void WearBackpack()
  356.     {
  357.         if (currentBackpackItem != null)
  358.         {
  359.             bool wasLeftHand = inventorySystem.leftHandItem == currentBackpackItem;
  360.             inventorySystem.UnequipItem(wasLeftHand);
  361.  
  362.             currentBackpackItem.transform.SetParent(backpackWearPosition);
  363.             currentBackpackItem.transform.localPosition = Vector3.zero;
  364.             currentBackpackItem.transform.localRotation = Quaternion.identity;
  365.  
  366.             Destroy(currentBackpackItem.GetComponent<Rigidbody>());
  367.             MeshCollider meshCollider = currentBackpackItem.GetComponent<MeshCollider>();
  368.             if (meshCollider != null) meshCollider.enabled = false;
  369.  
  370.             inventorySystem.EquipBackpack(currentBackpackItem);
  371.             currentBackpackItem = null;
  372.  
  373.             uiManager.ClosePrompt();
  374.             playerMovement.UpdateCarryingAnimations();
  375.  
  376.             uiManager.UpdateBackpackButtons(true);
  377.         }
  378.     }
  379.  
  380.     public void UnequipBackpack()
  381.     {
  382.         if (inventorySystem.IsBackpackEquipped)
  383.         {
  384.             Item backpack = inventorySystem.backpack;
  385.             inventorySystem.UnequipBackpack();
  386.  
  387.             MeshCollider meshCollider = backpack.GetComponent<MeshCollider>();
  388.             if (meshCollider != null) meshCollider.enabled = true;
  389.  
  390.             if (backpack.GetComponent<Rigidbody>() == null)
  391.             {
  392.                 backpack.gameObject.AddComponent<Rigidbody>();
  393.             }
  394.  
  395.             backpack.transform.SetParent(null);
  396.             backpack.transform.position = transform.position + transform.forward * 1.5f;
  397.  
  398.             playerMovement.UpdateCarryingAnimations();
  399.  
  400.             uiManager.UpdateBackpackButtons(false);
  401.         }
  402.     }
  403.  
  404.     private void EquipItem(Item item, bool isLeftHand, bool isTwoHanded)
  405.     {
  406.         inventorySystem.EquipItem(item, isLeftHand, isTwoHanded);
  407.         UpdateItemPosition(item.gameObject, isLeftHand);
  408.         ChangeItemLayer(item.gameObject, pickupLayer);
  409.         playerMovement.UpdateCarryingAnimations();
  410.     }
  411.  
  412.     public void UpdateItemPosition(GameObject itemObject, bool isLeftHand)
  413.     {
  414.         Transform objectHolder = isLeftHand ? leftObjectHolder : rightObjectHolder;
  415.         Item item = itemObject.GetComponent<Item>();
  416.         Vector3 positionOffset = isLeftHand ? item.leftPositionOffset : item.rightPositionOffset;
  417.         Vector3 rotationOffset = isLeftHand ? item.leftRotationOffset : item.rightRotationOffset;
  418.  
  419.         itemObject.transform.SetParent(objectHolder);
  420.         itemObject.transform.localPosition = positionOffset;
  421.         itemObject.transform.localRotation = Quaternion.Euler(rotationOffset);
  422.     }
  423.  
  424.     private void UpdateItemVisibility()
  425.     {
  426.         if (inventorySystem.leftHandItem != null)
  427.         {
  428.             inventorySystem.leftHandItem.gameObject.SetActive(!isPrecisionDrop);
  429.         }
  430.         if (inventorySystem.rightHandItem != null)
  431.         {
  432.             inventorySystem.rightHandItem.gameObject.SetActive(!isPrecisionDrop);
  433.         }
  434.     }
  435.  
  436.     public void ChangeItemLayer(GameObject itemObject, LayerMask newLayer)
  437.     {
  438.         itemObject.layer = (int)Mathf.Log(newLayer.value, 2);
  439.     }
  440.  
  441.     public bool IsPrecisionDropEnabled()
  442.     {
  443.         return isPrecisionDrop;
  444.     }
  445.  
  446.     // Optional: expose rotation toggle if PlayerMovement needs it
  447.     public void ToggleRotationMode()
  448.     {
  449.         if (isPrecisionDrop)
  450.         {
  451.             isRotating = !isRotating;
  452.             uiManager.ShowRotationMessage(isRotating);
  453.             if (isRotating && previewObjects.Count > 0)
  454.                 currentRotation = previewObjects[0].transform.rotation.eulerAngles;
  455.         }
  456.     }
  457. }
  458.  
Advertisement
Add Comment
Please, Sign In to add comment