RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 942602
Accepted
Artik Slayer
Artik Slayer
Asked:2020-02-09 00:30:24 +0000 UTC2020-02-09 00:30:24 +0000 UTC 2020-02-09 00:30:24 +0000 UTC

如何将物品放在盒子上以及如何将其带回 3D 中的角色

  • 772

最初,我是通过创建和删除一个对象来完成的,但我遇到了一个公共领域的项目,它可以做我想做的事情,但是是 2D 的。项目。

一般来说,据我了解,这个想法是我们通过ScriptableObject通过图层更改桌子上的精灵 。在此处输入图像描述

在此处输入图像描述

ps什么是OverlaySprite,一个空对象?为什么它像一个预制件,但是灰色的,虽然它是活动的。

主要代码:

作物资产:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "New Crop", menuName = "Crop")]
public class CropAsset : ScriptableObject
{
    public Sprite seedSprite;
    public Sprite deadSprite;
    public Sprite doneSprite;

    public bool seedIsOnGround = false;
}

庄稼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class Crop
{
    public CropAsset asset;

    public CropState state;

    private float growthLevel;
    private float waterLevel;
    private bool isDead;

    public bool Grow(float amount)
    {
        if (GetWaterState() == WaterState.Watered)
        {
            growthLevel += amount / 20f;
        }

        if (growthLevel >= 1f)
        {
            state = CropState.Done;
            return true;
        }

        return false;
    }

    public WaterState Dry(float amount)
    {
        waterLevel -= amount / 8f;
        return GetWaterState();
    }

    public WaterState GetWaterState ()
    {
        if (waterLevel > 0f)
        {
            return WaterState.Watered;
        }
        else if (waterLevel > -1f)
        {
            return WaterState.Dry;
        }
        else
        {
            state = CropState.Dead;
            return WaterState.Dead;
        }
    }

    public void Water ()
    {
        waterLevel = 1f;
    }

    public Crop (CropAsset a) {
        asset = a;
        state = CropState.Seed;
        growthLevel = 0f;
        waterLevel = 1f;
        isDead = false;
    }

    public bool HasCrop()
    {
        if (asset == null)
            return false;
        else
            return true;
    }

    public Sprite GetCropSprite()
    {
        if (asset == null)
            return null;

        switch (state)
        {
            case CropState.Seed:
                return asset.seedSprite;
            case CropState.Planted:
                return asset.seedSprite;
            case CropState.Dead:
                return asset.deadSprite;
            case CropState.Done:
                return asset.doneSprite;
        }

        Debug.LogError("WHAT?!");
        return asset.seedSprite;
    }

    public bool IsOnGround()
    {
        if (state == CropState.Planted && asset.seedIsOnGround)
            return true;
        else
            return false;
    }

    public Sprite GetDoneSprite()
    {
        return asset.doneSprite;
    }

    public string GetName()
    {
        if (asset == null)
            return null;

        return asset.name;
    }
}

public enum CropState
{
    Seed,
    Planted,
    Dead,
    Done
}

public enum WaterState
{
    Watered,
    Dry,
    Dead
}

工具:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "New Tool", menuName = "Tool")]
public class Tool : ScriptableObject
{
    public Sprite sprite;
    public ToolType toolType;
}

public enum ToolType
{
    Plow,
    Watercan
}

平铺:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TableTile : MonoBehaviour
{
    public SpriteRenderer overlay;

    public Crop crop;
    public Tool tool;

    private void Start()
    {
        if (crop.HasCrop())
            overlay.sprite = crop.GetCropSprite();
        else if (tool != null)
            overlay.sprite = tool.sprite;
    }

    public void Interact(Crop c, Tool t, PlayerInteraction player)
    {
        player.SetCrop(crop);
        crop = c;
        player.SetTool(tool);
        tool = t;

        if (tool != null)
            overlay.sprite = tool.sprite;
        else if (crop != null)
            overlay.sprite = crop.GetCropSprite();
        else
            overlay.sprite = null;
    }

}

我想做同样的事情,但对于 3D 对象。建议我将使用 Sprite 和 SpriteRenderer 的位置更改为 Mesh 和 MeshRenderer。

我的代码:

成分资产:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "New Ingredient", menuName = "Ingredient")]
public class IngredientAsset : ScriptableObject {

    public Mesh ingredientMesh;

}

在此处输入图像描述

成分:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class Ingredient : MonoBehaviour {

    public IngredientAsset asset;

    public Ingredient (IngredientAsset a) {
        asset = a;
    }

    public bool HasIngrediend()
    {
        if (asset == null)
            return false;
        else
            return true;
    }

    public Mesh GetIngrediendObject()
    {
        if (asset == null)
            return null;

        return asset.ingredientMesh;

    }
}

设备资产:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "New Equipment", menuName = "Equipment")]
public class EquipmentAsset : ScriptableObject {

    public Mesh equipmentMesh;

}

表框:

using System.Collections.Generic;
using UnityEngine;

public class TableBox : MonoBehaviour {

    public MeshRenderer overlay;

    public Ingredient ingredient;
    public EquipmentAsset equipment;

    private void Start()
    {
        if (ingredient.HasIngrediend())
            overlay.mesh = ingredient.GetIngrediendObject();
        else if (equipment != null)
            overlay.mesh = equipment.mesh;
    }

    public void Interact(Ingredient c, EquipmentAsset t, PlayerInteraction player)
    {
        player.SetIngredient(ingredient);
        ingredient = c;
        player.SetEquipment(equipment);
        equipment = t;

        if (equipment != null)
            overlay.sprite = equipment.mesh;
        else if (ingredient != null)
            overlay.mesh = ingredient.GetIngrediendObject();
        else
            overlay.mesh = null;
    }
}

Но начиная с момента создания моих ScriptableObjects типа mesh, в моей версии Crop ругается на overlay.mesh.

在此处输入图像描述

Сам стол:

在此处输入图像描述

Overlay: 在此处输入图像描述 Прошу помочь разобраться как преобразовать данную функцию к 3Д объектам. Правильно ли то что мне подсказали? Правильно ли так делать? Можно также но с префабами?

unity3d
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    user302909
    2020-02-09T03:02:27Z2020-02-09T03:02:27Z

    Для начала стоит пояснить, что ScriptableObject - это некого рода контейнер или, вернее, обертка над какими-то ресурсами, который можно инстанциировать и вообще взаимодействовать с ним, как с объектом.


    Теперь эта ошибка:

    在此处输入图像描述

    Вся проблема в том, что MeshRenderer не хранит меш, который рисует, он получает ее от MeshFilter. В 2д со спрайтами этим всем занимается ровно 1 объект, с мешами это не так.

    解决这个问题很简单——你需要存储一个对 的引用MeshFilter,MeshRenderer我们不关心它:

    public class TableBox : MonoBehaviour {
    
        public MeshFilter overlay;
    
        // ...
    
        private void Start()
        {
            if (ingredient.HasIngrediend())
                overlay.mesh = ingredient.GetIngrediendObject();
            else if (equipment != null)
                overlay.mesh = equipment.mesh;
        }
    
        public void Interact(Ingredient c, EquipmentAsset t, PlayerInteraction player)
        {
            // ...
            if (equipment != null)
                overlay.mesh = equipment.mesh;
            else if (ingredient != null)
                overlay.mesh = ingredient.GetIngrediendObject();
            else
                overlay.mesh = null;
        }
    }
    

    为什么在 Crop 字段中的 TableTile 脚本中的 2D 项目中是 CropAsset 类型的对象,但我有(我似乎也这样做)。成分资产不适合成分字段(不同的类型,但 2D 项目可以)。

    我根本不明白,你的成分字段有一个类型Ingredient,你想在其中放置一个类型的对象IngredientAsset。这就是为什么它不起作用。

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5