diff --git a/python-api-src/lib_unit.cpp b/python-api-src/lib_unit.cpp
index 358dbbb59e1bf77e7a964d8575238fe7970c3ea1..dd8a18b1700445c0ae0ab871846a22591e7b37a2 100644
--- a/python-api-src/lib_unit.cpp
+++ b/python-api-src/lib_unit.cpp
@@ -37,6 +37,7 @@ void define_unit(py::module & m)
         .def("build_target", &Unit::buildTarget)
         .def("train", &Unit::train)
         .def("morph", &Unit::morph)
+        .def("research", &Unit::research)
         .def("__hash__", [](const Unit & unit) { return std::hash<const sc2::Unit *>{}(unit.getUnitPtr()); })
         .def(py::self == py::self)
         .def("__repr__", [](const Unit & unit) { return "<Unit of type: '" + unit.getType().getName() + "'>"; });
diff --git a/src/Unit.cpp b/src/Unit.cpp
index 51ffd4c2496795a5fdcc9651606b1ae222fd3574..934db2c6e7bf7299e7fd890c4d345c44b185c04d 100644
--- a/src/Unit.cpp
+++ b/src/Unit.cpp
@@ -298,6 +298,12 @@ void Unit::morph(const UnitType & type) const
 #endif
 }
 
+void Unit::research(sc2::UpgradeID upgrade) const
+{
+    BOT_ASSERT(isValid(), "Unit is not valid");
+    m_bot->Actions()->UnitCommand(m_unit, m_bot->Data(upgrade).buildAbility);
+}
+
 bool Unit::isConstructing(const UnitType & type) const
 {
 	sc2::AbilityID buildAbility = m_bot->Data(type).buildAbility;
diff --git a/src/Unit.h b/src/Unit.h
index 2e4a360444ae9115a57934d9b4f215970ffccdbf..5770bd80b8b0d33faf89747bce3faaed0e993862 100644
--- a/src/Unit.h
+++ b/src/Unit.h
@@ -58,4 +58,5 @@ public:
     void buildTarget    (const UnitType & buildingType, const Unit & target) const;
     void train          (const UnitType & buildingType) const;
     void morph          (const UnitType & type) const;
+    void research       (sc2::UpgradeID upgrade) const;
 };