public abstract Entity CreateEntityInInventory(Entity entity, int prefabVariantIndex, InventorySlot inventorySlot);
public bool Check(Agent agent, ActionType actionType, ActionType otherActionType, InventorySlot inventorySlot, ModifierType modifierType, bool isTarget, bool allowNoActionTypes = false, bool ignoreModifierType = false) { if (!allowNoActionTypes && (actionTypes == null || actionTypes.Count == 0) && (otherActionTypes == null || otherActionTypes.Count == 0)) { Debug.LogError(agent.name + ": has an ActionTypeModifier with no Action Types and no Other Action Types. Please Fix."); return(false); } return(isTarget == this.isTarget && (ignoreModifierType || modifierType == this.modifierType) && (actionTypes == null || actionTypes.Count == 0 || actionTypes.Contains(actionType)) && (otherActionTypes == null || otherActionTypes.Count == 0 || otherActionTypes.Contains(otherActionType)) && (inventorySlots != null || inventorySlots.Count == 0 || inventorySlots.Contains(inventorySlot)) && (agentTypeConstraints != null || agentTypeConstraints.Count == 0 || AgentTypeConstraintsCheck(agent))); }
// Uses 2D Physics public override Vector3 FindDropLocation(Entity entity, Entity entityDropped, InventorySlot inventorySlot) { // First see if a drop location(s) are set on entity foreach (Transform child in entity.transform) { if (child.name == "DropSpot") { // TODO: Check to see if this drop spot is occupied return(child.transform.position); } } // Pick a random spot on the NavMesh that has no Entities on it already Vector3 startLocation = entity.transform.position; Vector3 agentForward = entity.transform.forward; // Go out far enough to clear the droppedBy Entity // TODO: Won't handle multiple renderer GameObjects Renderer renderer = entity.GetComponentInChildren <Renderer>(); float dropDistance = Mathf.Max(renderer.bounds.extents.x, renderer.bounds.extents.y) + inventorySlot.dropDistance; Vector3 dropLocation = Vector3.positiveInfinity; int attempts = 0; while (dropLocation.x == float.PositiveInfinity && attempts < 20) { Vector3 sampleLocation; if (inventorySlot.dropType == InventorySlot.DropType.RandomRadius) { Vector2 randomDirection2 = UnityEngine.Random.insideUnitCircle.normalized; Vector3 randomDirection = new Vector3(randomDirection2.x, randomDirection2.y, 0); sampleLocation = startLocation + dropDistance * randomDirection; } else { float offsetDegrees; if (attempts % 2 == 0) { offsetDegrees = attempts * 15; } else { offsetDegrees = attempts; } Debug.Log("Start Location = " + startLocation + " - Agent Forward = " + agentForward); Vector3 newDirection = Quaternion.Euler(0, offsetDegrees, 0) * agentForward; Debug.Log("New Direction = " + newDirection); sampleLocation = startLocation + dropDistance * newDirection; Debug.Log("Sample Location = " + sampleLocation); } // Place it on top of the ground Collider2D collider = Physics2D.OverlapCircle(sampleLocation, .1f, LayerMask.GetMask("Ground")); if (collider != null) { dropLocation = new Vector3(sampleLocation.x, sampleLocation.y, 0); } else { Debug.LogError(entity.name + " is trying to drop inventory (" + name + ") - OverlapCircle did not hit the ground."); } ++attempts; } if (dropLocation.x == float.PositiveInfinity) { Debug.Log(entity.name + " is trying to drop inventory (" + name + ") - 10 attempts couldn't find a drop spot."); Vector2 randomDirection2 = UnityEngine.Random.insideUnitCircle.normalized; Vector3 randomDirection = new Vector3(randomDirection2.x, 0, randomDirection2.y); dropLocation = startLocation + dropDistance * randomDirection; } return(dropLocation); }
public GameObject GetSlotMapping(InventorySlot inventorySlot, out bool makeDisabled, bool alreadyAdded = false) { makeDisabled = false; InventorySlotMapping inventorySlotMapping = inventorySlotMappings.Find(x => x.inventorySlot == inventorySlot); if (inventorySlotMapping == null) { Debug.LogError(name + ": Trying to put an Entity in an InventorySlot (" + inventorySlot + ") Location that does " + "not have an InventorySlotMapping. (On the Entity Component - please set the InventorySlotMapping variable)"); return(null); } int numInSlot = inventoryType.GetInventorySlotAmount(this, inventorySlot); if (alreadyAdded) { --numInSlot; } int locationIndex = -1; switch (inventorySlot.slotType) { case InventorySlot.SlotType.Invisible: case InventorySlot.SlotType.OwnerInvisible: locationIndex = 0; break; case InventorySlot.SlotType.Location: if (numInSlot > 1) { Debug.LogError(name + ": Entity.GetSlotMapping failed to find slot location in InventorySlot = " + inventorySlot.name); return(null); } locationIndex = 0; break; case InventorySlot.SlotType.MultiLocation: locationIndex = numInSlot; if (numInSlot >= inventorySlotMapping.locations.Count) { if (inventorySlot.extraBecomesInvisible) { // Place item in the last slot and tell caller it should be disabled makeDisabled = true; locationIndex = inventorySlotMapping.locations.Count - 1; } else { Debug.LogError(name + ": Entity.GetSlotMapping failed to find slot location in InventorySlot = " + inventorySlot.name); return(null); } } break; case InventorySlot.SlotType.Skinned: Debug.LogError("InventorySlot (" + inventorySlot.name + ") - Skinned Slot type is currently not supported."); return(null); } if (locationIndex >= inventorySlotMapping.locations.Count) { Debug.LogError(name + ": GetSlotMapping (" + inventorySlot.name + ") tried to use a inventorySlotMapping.locations " + "that doesn't exist: " + locationIndex + " >= " + inventorySlotMapping.locations.Count); return(null); } return(inventorySlotMapping.locations[locationIndex]); }
// AgentEvent can't be in an Entity's inventory public override Entity CreateEntityInInventory(Entity entity, int prefabVariantIndex, InventorySlot inventorySlot) { Debug.LogError("Trying to create an AgentEventType Entity inside an inventory."); return(null); }
public override void ChangeSkin(WorldObject worldObject, GameObject newPrefab, int skinPrefabIndex) { // -1 means it didn't match any so go back to original if (skinPrefabIndex == -1) { newPrefab = worldObject.PrefabVariant(); } Debug.Log(worldObject.name + ": Base3DIT.ChangeSkin -> " + skinPrefabIndex + " - " + (newPrefab != null ? newPrefab.name : "Activate")); GameObject skinGameObject = null; foreach (Transform child in worldObject.transform) { if (child.name == worldObject.worldObjectType.skinGameObjectName) { skinGameObject = child.gameObject; } } if (skinGameObject == null) { Debug.LogError(name + ": Unable to find a child name that equals \"" + worldObject.worldObjectType.skinGameObjectName + "\" as specificied in its WorldObjectType.skinGameObjectName"); return; } WorldObjectType.SkinPrefabMapping skinPrefabMapping = worldObject.worldObjectType.skinPrefabMappings[skinPrefabIndex]; if (skinPrefabMapping.changeType == WorldObjectType.SkinPrefabMapping.ChangeType.ToggleActive) { int currentIndex = skinPrefabMapping.childStartIndex + (int)worldObject.completePoints; // Find GameObject to activate int index = 0; if (skinPrefabMapping.enableType == WorldObjectType.SkinPrefabMapping.EnableType.EnableBodyChildren) { foreach (Transform child in skinGameObject.transform) { if (index == currentIndex) { child.gameObject.SetActive(true); break; } ++index; } } else { bool foundGameObject = false; foreach (Transform parent in skinGameObject.transform) { foreach (Transform child in parent.transform) { if (index == currentIndex) { child.gameObject.SetActive(true); foundGameObject = true; break; } ++index; } if (foundGameObject) { break; } } } // Figure out what needs to be deactivated if (skinPrefabMapping.disableType == WorldObjectType.SkinPrefabMapping.DisableType.First) { skinGameObject.transform.GetChild(0).gameObject.SetActive(false); } else if (skinPrefabMapping.disableType == WorldObjectType.SkinPrefabMapping.DisableType.Previous) { skinGameObject.transform.GetChild(currentIndex - 1).gameObject.SetActive(false); } } else { Destroy(skinGameObject); GameObject newGameObject = Instantiate(newPrefab, worldObject.transform); newGameObject.name = worldObject.worldObjectType.skinGameObjectName; newGameObject.layer = worldObject.gameObject.layer; Debug.Log("Changed the prefab for " + worldObject.name + ": Prefab Name = " + newPrefab.name); } // Check to see if transform info should change if its in inventory if (worldObject.inEntityInventory != null) { Entity inventoryOwner = worldObject.inEntityInventory; InventorySlot inventorySlot = inventoryOwner.inventoryType.GetEntitySlot(inventoryOwner, worldObject); GameObject gameObject = worldObject.worldObjectType.GetTransformMapping(inventorySlot, inventoryOwner, worldObject); worldObject.transform.localPosition = gameObject.transform.position; worldObject.transform.localRotation = gameObject.transform.rotation; worldObject.transform.localScale = gameObject.transform.localScale; } worldObject.totalAIManager.UpdateAllNavMeshes(); worldObject.currentSkinPrefabIndex = skinPrefabIndex; }
// Uses 3D Physics public override Vector3 FindDropLocation(Entity entity, Entity entityDropped, InventorySlot inventorySlot) { // Pick a random spot on the NavMesh that has no Entities on it already Vector3 startLocation = entity.transform.position; Vector3 agentForward = entity.transform.forward; // Go out far enough to clear the droppedBy Entity // TODO: Won't handle multiple renderer GameObjects Renderer renderer = entity.GetComponentInChildren <Renderer>(); float dropDistance = Mathf.Max(renderer.bounds.extents.x, renderer.bounds.extents.z) + inventorySlot.dropDistance; Vector3 dropLocation = Vector3.positiveInfinity; int attempts = 0; while (dropLocation.x == float.PositiveInfinity && attempts < 20) { Vector3 sampleLocation; if (inventorySlot.dropType == InventorySlot.DropType.RandomRadius) { Vector2 randomDirection2 = UnityEngine.Random.insideUnitCircle.normalized; Vector3 randomDirection = new Vector3(randomDirection2.x, 0, randomDirection2.y); sampleLocation = startLocation + dropDistance * randomDirection; } else { float offsetDegrees; if (attempts % 2 == 0) { offsetDegrees = attempts * 15; } else { offsetDegrees = attempts; } Debug.Log("Start Location = " + startLocation + " - Agent Forward = " + agentForward); Vector3 newDirection = Quaternion.Euler(0, offsetDegrees, 0) * agentForward; Debug.Log("New Direction = " + newDirection); sampleLocation = startLocation + dropDistance * newDirection; Debug.Log("Sample Location = " + sampleLocation); } // Place it on top of the ground if (Physics.BoxCast(sampleLocation + Vector3.up * 30, new Vector3(.5f, .5f, .5f), Vector3.down, out RaycastHit hit, Quaternion.identity, 35f, LayerMask.GetMask("Ground", "Agent", "WorldObject"), QueryTriggerInteraction.Ignore)) { Debug.Log(Mathf.Abs(hit.point.y - sampleLocation.y)); if (hit.collider.gameObject.layer == LayerMask.NameToLayer("Ground") && Mathf.Abs(hit.point.y - sampleLocation.y) < 2f) { dropLocation = new Vector3(sampleLocation.x, hit.point.y, sampleLocation.z); } }
// WorldObject is being created as an Entity's inventory // TODO: Should this just be one method in InventoryType? public override Entity CreateEntityInInventory(Entity entity, int prefabVariantIndex, InventorySlot inventorySlot) { if (inventorySlot.slotType != InventorySlot.SlotType.Skinned) { GameObject parentGameObject = entity.GetSlotMapping(inventorySlot, out bool makeDisabled); if (prefabVariants == null || prefabVariants.Count < 1) { Debug.LogError("No prefabVariants for " + name + ". Unable to create WorldObjectType In Inventory: " + name + " in Entity: " + entity.name); return(null); } if (prefabVariantIndex < 0 || prefabVariantIndex > prefabVariants.Count - 1) { Debug.LogError("Invalid prefabVariantIndex (" + prefabVariantIndex + ") for " + name + ". Unable to create " + "WorldObjectType In Inventory: " + name + " in Entity: " + entity.name); return(null); } GameObject prefabVariant = prefabVariants[prefabVariantIndex]; prefabVariant.SetActive(false); GameObject newGameObject = Instantiate(prefabVariant, parentGameObject.transform); newGameObject.layer = LayerMask.NameToLayer("Default"); if (inventorySlot.slotType != InventorySlot.SlotType.Invisible && !makeDisabled) { newGameObject.SetActive(true); } prefabVariant.SetActive(true); Entity newEntity = newGameObject.GetComponent <Entity>(); newEntity.inEntityInventory = entity; if (inventorySlot.slotType != InventorySlot.SlotType.Invisible) { GameObject gameObject = GetTransformMapping(inventorySlot, entity, newEntity); newGameObject.transform.localPosition = gameObject.transform.position; newGameObject.transform.localRotation = gameObject.transform.rotation; newGameObject.transform.localScale = gameObject.transform.localScale; } return(newEntity); } else { // TODO: Skinned inventory slot } return(null); }